【问题标题】:Binding Element to Property from Inherited Data Context从继承的数据上下文将元素绑定到属性
【发布时间】:2015-07-25 01:50:04
【问题描述】:

我有一个 WPF 控件窗格,其中包含 16 个相同的子控件,其中包含一个组合框,该组合框需要绑定到后面的父控件代码中的列表。我真的很难让这个列表绑定,直到我发现这个:Binding objects defined in code-behind

在父控件上设置DataContext="{Binding RelativeSource={RelativeSource Self}}" 允许我直接在子控件上绑定组合框。

问题是现在我想创建一个数据模板来正确显示列表项,但是我在绑定或相对源中没有显示任何内容。

ControlPane.xaml

<UserControl
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         x:Class="ControlPane"
         x:Name="CtrlPaneWpf"
         DataContext="{Binding RelativeSource={RelativeSource Self}}"
         > 

ControlPane.xaml.cs

public class TwoStringClass
{
    public string string1;
    public string colorHex;
}

public ObservableCollection<TwoStringClass> TwoStringClass1
{
    get
    {
        ObservableCollection<TwoStringClass> cmbclrs = new ObservableCollection<TwoStringClass>();
        cmbclrs.Add(new TwoStringClass() { string1 = "This", colorHex = "#FF0000" });
        cmbclrs.Add(new TwoStringClass() { string1 = "That", colorHex = "#FF352E2"  });
        cmbclrs.Add(new TwoStringClass() { string1 = "The Other", colorHex = "#FFF4F612"  });
        return cmbclrs;
    }    
}

ChildControl.xaml

<UserControl
            x:Name="ChildControl"
            >
            <ComboBox x:Name="cmbFontColor" ItemsSource="{Binding TwoStringClass1}" >
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Text="{Binding string1}"  />
                            <Rectangle Fill="{Binding colorHex}" />
                        </StackPanel>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
</UserControl>

我知道 Binding 正在工作,因为我在 Combobox 中获得了正确数量的(空白)项目,并且如果我删除 ItemTemplate 可以看到类名。

我一生都想不通为什么绑定到属性名称在这里不起作用,就像列表来自控件自己的代码时那样。

我必须向 TextBlock 绑定添加一些其他信息,但无论我尝试什么 DataContext 或 RelativeSource,我总是得到空白项。

【问题讨论】:

    标签: c# wpf xaml combobox


    【解决方案1】:

    WPF 中的数据绑定仅适用于公共属性,不适用于字段。您的项目类应如下所示:

    public class TwoStringClass
    {
        public string string1 { get; set; }
        public string colorHex { get; set; }
    }
    

    也就是说,有广泛接受的命名约定,根据这些约定,您应该使用Pascal case 作为属性名称,例如String1ColorHex

    【讨论】:

      【解决方案2】:

      我相信您的问题的答案与我最近发布的问题的答案相同,该问题由 StewBob 回答。这是我对他的回答稍作修改的版本,它也应该可以解决您遇到的问题。

      您可以在此处查看我的原始帖子:WPF ListBox with CheckBox data template - Binding Content property of Checkbox not working

      我看到您添加了“This”、“That”和“The Other”作为您的数据源,大概是为了简单地将这个问题发布给 SO。请注意,如果您真正的底层数据源可以更改,则在执行 DataBinding 时,您的类需要实现 INotifyPropertyChanged 以使数据正确显示在 UI 中。一个例子:

      public class TwoStringClass: INotifyPropertyChanged
      {
      
        private string _String1;
        private string _ColorHex;
      
        public string String1
        {
          get
          {
            return _String1;
          }
          set
          {
            if (value != _String1)
            {
              _String1 = value;
              NotifyPropertyChanged("String1");
            }
          }
        }
      
        public string ColorHex
        {
          get
          {
            return _ColorHex;
          }
          set
          {
            if (value != _ColorHex)
            {
              _ColorHex = value;
              NotifyPropertyChanged("ColorHex");
            }
          }
        }
      
        private void NotifyPropertyChanged(string info)
        {
          if (PropertyChanged != null)
          {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
          }
        }
      
        public event PropertyChangedEventHandler PropertyChanged;
      }
      

      这显示了类、两个属性以及实现 INotifyPropertyChanged 所需的事件和方法。

      【讨论】:

      • 仅供参考。仅当您需要在绑定的源属性更改其值时更新潜在绑定时,才需要实现 INotifyPropertyChanged。只要这不是必需的(问题似乎就是这种情况),不实现此接口是完全有效的。绑定本身运行良好,无需任何更改通知。因此,您的陈述“您的类需要实现 INotifyPropertyChanged 以使数据正确显示在 UI 中”是不正确的。不实现接口绝不是“错误”。
      • 错误评论是指基础数据正在发生变化的情况,如我的评论中所述。原始发帖人在他的问题中添加了字符串“This”、“That”和“The Other”,这可能是为了将此问题发布给 SO 的简化数据。偶然发现这一点并实施此解决方案而没有看到对此仅适用于静态数据源的任何引用的人将遇到错误,而指出差异的答案以及您可能需要 iNotifyPropertyChanged 的​​原因不会导致错误(在应用程序中)。
      猜你喜欢
      • 1970-01-01
      • 2013-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-10
      相关资源
      最近更新 更多