繁体   English   中英

关于WPF绑定的困惑

[英]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>

重申一下,模板就是这样-用于显示数据的模板。 它应该是可重用的,您应该能够将其绑定到所需的任何模型。 经验法则-绑定到实际数据的数据应在控件而不是模板上发生。

  1. 就像Igor所说的那样,您需要在最外面的ItemsControl指定ItemsSource={Binding DayNumbers} ,否则,它将绑定到DataContext ,后者是CalendarViewModel ,并且不是IEnumerable

  2. 一旦你这样做,它将适用<DataTemplate x:Key="PanelOfPanels">对于内部每个项目DayNumbers 需要注意的是DataContext所述的DataTemplate的每个元素中DayNumbers ,这是类型ObservableCollection<int> 在这里,您不能指定ItemsSource="{Binding Path=DayNumbers}"因为DayNumbersObservableCollection<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}}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM