2010-05-21 105 views
0

我試圖綁定排列stackpanels到2D的ObservableCollection按鈕的二維數組...混淆WPF結合

然而,我怕我不明白一些事情結合非常初級的。

我的XAML:

<Window.Resources> 
    <DataTemplate x:Key="ItemsAsButtons"> 
     <Button Content="{Binding}" Height="100" Width="100"/> 
    </DataTemplate> 
    <DataTemplate x:Key="PanelOfPanels"> 
     <ItemsControl ItemsSource="{Binding Path=DayNumbers}" ItemTemplate=" {DynamicResource ItemsAsButtons}"> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <StackPanel Orientation="Horizontal"/> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
     </ItemsControl> 
    </DataTemplate> 
    </Window.Resources> 

... 
     <ItemsControl x:Name="DaysPanel" Grid.ColumnSpan="7" Grid.Row="2" 
         ItemTemplate="{DynamicResource PanelOfPanels}"/> 

我的C#代碼: 後端:

/// <summary> 
/// Window BE for Calendar.xaml 
/// </summary> 
public partial class Calendar : Window 
{ 

    private CalendarViewModel _vm; 
    public Calendar() 
    { 
     InitializeComponent(); 
     _vm = new CalendarViewModel(); 
     this.DataContext = _vm; 
    } 
} 

視圖模型:

class CalendarViewModel 
{ 
    CalendarMonth _displayedMonth; 
    EventCalendar _calendar; 

    public CalendarViewModel() 
    { 
     _displayedMonth = new CalendarMonth(); 
    } 

    public ObservableCollection<ObservableCollection<int>> DayNumbers 
    { 
     get 
     { 
      return _displayedMonth.DayNumbers; 
     } 
    } 
} 

我試圖從值來填充按鈕CalendarViewModel.DayNumbers - 但按鈕不出現。我明顯在做我的約束力有問題。

回答

2
  1. 像伊戈爾說,你需要指定最外層ItemsControlItemsSource={Binding DayNumbers},否則,它結合了DataContext,這是CalendarViewModel,它不是IEnumerable

  2. 一旦你這樣做,它將適用<DataTemplate x:Key="PanelOfPanels">DayNumbers內的每個項目。請注意,DayNumbers中的每個元素中的DataTemplateDataContext,其類型爲ObservableCollection<int>。在這裏,您不能指定ItemsSource="{Binding Path=DayNumbers}",因爲DayNumbers不是ObservableCollection<int>中的有效屬性。相反,因爲ObservableCollection<int>已經是IEnumerable,所以應該沒有指定ItemsSource,因爲它默認會綁定到DataContext

  3. 最後,它進入你最內層的<DataTemplate x:Key="ItemsAsButtons">,你可以把按鈕放在那裏,就像你做的那樣。

希望能夠澄清一點。對不起,我沒有環境來測試它,並給你解決方案。

調試WPF綁定並不簡單。一個技巧是,你可以使用虛擬轉換,並且設置斷點在Convert方法,看看它結合。

public class DebugConverter1 : IValueConverter 
    { 
    #region IValueConverter Members 

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return value; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return value; 
    } 

    #endregion 
    } 

{Binding Converter={StaticResource debugConverter1}} 
+0

現在我明白了 - 我需要在上層列表中指定一個純綁定,我可以看到什麼伊戈爾現在說。 – Vladislav 2010-05-21 09:12:41

3

將您所有的DynamicResource更改爲StaticResource。這不應該阻止它的工作,但可能在運行時效率低下。查看WPF資源概述this page

另外您的ItemsControl不綁定到DayNumbers。添加像這樣綁定:

<ItemsControl x:Name="DaysPanel" Grid.ColumnSpan="7" Grid.Row="2" 
        ItemTemplate="{StaticResource PanelOfPanels}" 
        ItemsSource={Binding DayNumbers}/> 

當你設置你設置哪些對象將是針對整個窗口的默認綁定源日曆窗口的DataContext。您沒有指定ViewModel的哪個屬性綁定到ItemsControl。這就是上面的代碼所做的。

編輯因爲要覆蓋的ItemsControl的項目模板,並提供一個收集容器那裏,你需要提供ItemsSource了它。語法{Binding}僅意味着綁定到每個成員或枚舉,在這種情況下ObservableCollection<int>

只是重申一下,模板就是 - 用於顯示數據的模板。它應該是可重用的,你應該能夠將它綁定到你想要的任何模型。經驗法則 - 數據與實際數據的綁定應該發生在控件上,而不是模板上。

+0

不模板代碼提供的綁定?我嘗試添加你建議的代碼行到ItemsControl的實際調用,但這並沒有幫助,但沒有幫助。 。 – Vladislav 2010-05-21 02:57:35

+0

我錯過了位。從來沒有這樣試過,看起來很尷尬。該模板應該定義控件的外觀和感覺,而不是綁定到數據。 – 2010-05-21 03:13:37

+0

模板中的線原來是強制性的,但必須改變到的ItemsSource =「{結合}」。 你說模板不應該提供綁定 - 有沒有辦法解決這個問題(其他手動綁定在C#代碼中) – Vladislav 2010-05-21 09:14:43