【问题标题】:How to bind a dependency property to a control in WPF?如何将依赖属性绑定到 WPF 中的控件?
【发布时间】:2011-03-28 01:56:44
【问题描述】:

我创建了一个Day 类:

public class Day
{
    public int DayOfMonth
    {
        get { return dayOfMonth; }
    }
    public List<Entry> CalendarDayItems
    {
        get { return calendarDayItems; }
        set { calendarDayItems = value; }
    }

    private DateTime date;
    private int dayOfMonth;
    private List<Entry> calendarDayItems;

    public Day(DateTime date, List<Entry> entries)
    {
        this.date = date;
        this.dayOfMonth = date.Day;
        this.calendarDayItems = entries;
    }
}

接下来,我创建了一个 WPF UserControl,我希望将天的集合绑定到 ItemsControl。我创建了一个依赖属性ObservableCollection&lt;Day&gt; Days,它绑定到ItemsControl。这是 XAML:

<UserControl ... Name="CalendarMonthViewControl">
...
<ItemsControl 
    ItemsSource="{Binding ElementName=CalendarMonthViewControl, Path=Days}">
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <UniformGrid Rows="6" Columns="7" />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
  <ItemsControl.ItemTemplate>
    <DataTemplate DataType="Day">
      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <!-- The following two bindings don't work -->
        <TextBlock 
            Grid.Column="0" 
            Text="{Binding Path=DayOfMonth}" />
        <ItemsControl 
            Grid.Column="1" 
            ItemsSource="{Binding Path=CalendarDayItems}">
        </ItemsControl>
      </Grid>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>
...

我有几个问题:

  1. 我是否使用正确的方法将依赖属性绑定到ItemsControl,即是否建议命名控件,然后将其作为绑定源引用?
  2. 主要问题是TextBlock 和第二个ItemsControl 不会分别绑定到Day 类的DayOfMonthCalendarDayItems 属性。

【问题讨论】:

  • @Boris 当你说“不会绑定”时,你的意思是你看不到这些属性的初始值(并且 VS 的输出窗口显示绑定错误)还是改变了这些属性不显示?
  • @grantnz 我的意思是当我运行应用程序时,TextBlockItemsControl 没有显示任何数据,DayOfMonth 值和CalendarDayItems 的列表没有显示。它们只是空白,但没有错误或异常。
  • 就好像绑定试图在控件上找到这些属性,而不是在集合中的Day 项...
  • 如果您在调试器中运行您的应用程序,输出窗口中是否有任何绑定错误?
  • @Andy,输出窗口显示调试器中的错误。这使我找到了答案并使绑定工作。请发表您的评论作为答案,以便我将其标记为正确。

标签: wpf binding


【解决方案1】:

如果您在调试器中运行您的应用程序,任何与绑定相关的错误都将显示在“输出”窗口中。这可用于找出绑定不起作用的原因。

【讨论】:

  • 在输出窗口中,我发现DayOfMonthMonthEntries 是不存在的属性。一旦我检查了Day 类,我注意到我已经为这些属性设置了internal 访问器。将它们更改为 public 解决了绑定问题。感谢安迪为我指明了正确的方向。
【解决方案2】:

有一些解决 Q2 的好建议,但对于 Q1,我建议您为 UserControl 设置 DataContext,然后在 ItemsControl 中使用 ItemsSource="{Binding Path=Days}"

这使您可以轻松地将 DataContext 替换为另一个,例如对您的控件进行简单测试。这也意味着如果Days或其他属性用于您的UserControl中的其他控件,则无需重复ElementName标签。

这种机制通常与 Model-View-ViewModel (MVVM) 设计模式(请参阅MSDN)一起使用,其中 ViewModel 是 View 的 DataContext。

在您的示例中,您可以直接在 XAML 中设置 DataContext,使用类似的方法:

<UserControl DataContext="{Binding Path=CalendarMonthViewControl}}" ... />

或者您可以在其中设置代码隐藏文件。

【讨论】:

  • 不同意,没有必要在每个孔中都放置一个 MVVM 模式。简单的控件应该以常规的方式实现,MVVM 不会让它变得更容易,可能会让它变得更糟。 OP 对 Dependency 属性的使用是正确的。此外,您的回答对我来说似乎还不清楚,您没有回答第二个问题,对于第一个问题,您只有几句话关于 what 应该更改。你没有说应该如何以及谁应该设置DataContext
  • @Snowbear,您是否同意我以可推荐的方式将依赖属性 Days 绑定到 ItemsControl?此绑定有效,但我希望提高我的技能,所以使用DataContext 可能是更好的解决方案?
  • @Boris,IMO,您绑定它的方式是正确的,还有其他略有不同的选项,但它们不会给您带来太多好处。如果我要编写这样的控件,我会使用您选择的方法,我没有看到更好的方法。附言很抱歉在回答中发送垃圾邮件。
  • @Snowbear,我并不是说这个控件一定需要使用 MVVM,但它是设置 DataContext 的一个例子。我会更新我的答案以澄清。
猜你喜欢
  • 1970-01-01
  • 2020-12-22
  • 2023-03-26
  • 2012-03-22
  • 1970-01-01
  • 1970-01-01
  • 2013-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多