2010-03-10 9 views
15

Używam ItemsControl, gdzie ItemsPanel jest ustawiona na płótnie (zobacz this pytanie więcej informacji w tle). ItemsControl wykonuje jak chcę, i to działa jak czar podczas dodawania element podrzędny ręcznie przez wprowadzenie go do ItemsControl.Items:Podczas korzystania z ItemsControl ItemsControl.ItemsPanel jest ustawiona na Canvas, ContenPresenter przychodzi i podział moje właściwości Canvas na dzieciach [WPF]

<ItemsControl> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Canvas IsItemsHost="True" /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.Items> 
     <Button Canvas.Left="500" Content="Button Text" /> 
    </ItemsControl.Items> 
</ItemsControl> 

Uwaga własnością Canvas.Left na przycisku. Działa to jak czar, a przycisk znajduje się 500 pikseli od lewej strony lewej strony ItemsControl. Wspaniały!

jednak, gdy jestem definiowania ItemsSource wiązania do wykazu, Canvas.left nie ma żadnego wpływu:

<ItemsControl ItemsSource="{Binding Elements}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Canvas IsItemsHost="True" /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <Button Canvas.Left="500" Content="Button Text" /> 
     </DataTemplate>  
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

sprawdzając w czasie wykonywania aplikacji, widzę jedną różnicę. Kontener ContentPresenter został dodany między płótnem a przyciskiem.

Jak ustawić właściwość Canvas.Left w samym programie ContentPresenter? Czy istnieje inny sposób rozwiązania tego problemu?

Dziękuję wszystkim!

Odpowiedz

3

istnieje kilka rozwiązań przybywających do mojego umysłu:

  1. użyć układ/rendertransform zamiast załączony właściwość
  2. margines użycie zamiast załączony właściwość
  3. pochodzą z ItemsControl i zastąpić zachowanie w jaki sposób generowane są kontenery podrzędne. (GetContainerForItemOverride, IsItemItsOwnContainerOverride). Ten artykuł wyjaśnia całkiem ładnie, jak to działa: http://drwpf.com/blog/2008/07/20/itemscontrol-g-is-for-generator/
25

Możliwe jest ustawienie właściwości Canvas.Left użyciu ItemContainerStyle:

<ItemsControl ItemsSource="{Binding Elements}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <Canvas IsItemsHost="True" /> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Button Content="Button Text" /> 
      </DataTemplate>  
     </ItemsControl.ItemTemplate> 
    <ItemsControl.ItemContainerStyle> 
     <Style> 
      <Setter Property="Canvas.Left" Value="500" /> 
     </Style> 
    </ItemsControl.ItemContainerStyle> 
</ItemsControl> 
+0

wydaje się dziwne, ale ten pracował dla mnie. – bryanbcook

+1

Możesz również powiązać wartość w ItemContainerStyle i użyje tego samego przedmiotu, którego DataTemplate używa jako źródła. :-) –

+0

Jesteś moim bohaterem dzisiaj. Dziękuję. –

2

przycisk nie mają „płótna” obiekt, to co robisz to nawiązywanie względnego połączenia z kontrolą hostingu, jednak ponieważ element i płótno są w różnych szablonach, nie ma bezpośredniego połączenia, dlatego też Canvas.Left nie ma znaczenia przed uruchomieniem.

dlatego Twoja metoda nie może znaleźć lewej do ustawienia, więc traci zmianę.

Jednak Setery są realizowane tylko w czasie wykonywania tak

<Setter Property="Canvas.Left" Value="500" /> 

będzie działać dopiero po obiekty zostały wygenerowane, a tym samym mają względny relacji.

W przeciwnym wypadku można użyć margines, który nie należy do obiektu przycisku, ale znowu jest interpretowane tylko w czasie wykonywania