[英]Confusion about WPF binding
我试图将排列在堆栈面板中的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中的值填充按钮-但是按钮没有出现。 我的绑定显然做错了。
将所有DynamicResource
更改为StaticResource
。 这不应该停止它的工作,但是可能在运行时效率低下。 查看此页面以获取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>
。
重申一下,模板就是这样-用于显示数据的模板。 它应该是可重用的,您应该能够将其绑定到所需的任何模型。 经验法则-绑定到实际数据的数据应在控件而不是模板上发生。
就像Igor所说的那样,您需要在最外面的ItemsControl
指定ItemsSource={Binding DayNumbers}
,否则,它将绑定到DataContext
,后者是CalendarViewModel
,并且不是IEnumerable
。
一旦你这样做,它将适用<DataTemplate x:Key="PanelOfPanels">
对于内部每个项目DayNumbers
。 需要注意的是DataContext
所述的DataTemplate
的每个元素中DayNumbers
,这是类型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}}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.