我正在尝试将排列在stackpanels中的2D按钮数组绑定到2D ObservableCollection ......
然而,我担心我不明白一些关于约束力的基本内容。
我的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;
}
}
ViewModel:
class CalendarViewModel
{
CalendarMonth _displayedMonth;
EventCalendar _calendar;
public CalendarViewModel()
{
_displayedMonth = new CalendarMonth();
}
public ObservableCollection<ObservableCollection<int>> DayNumbers
{
get
{
return _displayedMonth.DayNumbers;
}
}
}
我正在尝试使用CalendarViewModel.DayNumbers中的值填充按钮 - 但按钮不会出现。我的绑定显然做错了。
答案 0 :(得分:3)
将您的所有DynamicResource
更改为StaticResource
。这不应该阻止它工作,但在运行时可能效率低下。查看this page以获取WPF资源概述。
此外,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>
。
重申一下,模板就是 - 用于显示数据的模板。它应该是可重用的,你应该能够将它绑定到你想要的任何模型。经验法则 - 数据绑定到实际数据应该发生在控件上,而不是模板上。
答案 1 :(得分:2)
像Igor所说,你需要在最外层ItemsSource={Binding DayNumbers}
指定ItemsControl
,否则,它会绑定到DataContext
,CalendarViewModel
就是IEnumerable
不是<DataTemplate x:Key="PanelOfPanels">
。
一旦这样做,它将对DayNumbers
内的每个项目应用DataContext
。请注意DataTemplate
中每个元素中DayNumbers
的{{1}},其类型为ObservableCollection<int>
。在此处,您无法指定ItemsSource="{Binding Path=DayNumbers}"
,因为DayNumbers
不是ObservableCollection<int>
中的有效属性。相反,由于ObservableCollection<int>
已经是IEnumerable
,因此不应指定ItemsSource
,因为它默认会绑定到DataContext
。
最后,它会转到你最内心的<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}}