将继承数据上下文中的元素绑定到 属性
Binding Element to Property from Inherited Data Context
我有一个 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>
我知道绑定正在工作,因为我在组合框中获得了正确数量的(空白)项目,并且如果我删除 ItemTemplate 可以看到 class 名称。
我一辈子都弄不明白为什么绑定到 属性 名称在这里不起作用,因为它在列表来自控件自己的代码后面时起作用。
我一定有一些其他信息需要添加到 TextBlock 绑定中,但无论我尝试什么 DataContext 或 RelativeSource,我总是得到空白项。
WPF 中的数据绑定仅适用于 public 属性,不适用于字段。您的商品 class 应如下所示:
public class TwoStringClass
{
public string string1 { get; set; }
public string colorHex { get; set; }
}
也就是说,有广泛接受的命名约定,根据该约定,您应该使用 Pascal case 作为 属性 名称,例如String1
和 ColorHex
.
我相信您的问题的答案与我最近发布的一个问题的答案相同,该问题由 StewBob 回答。这是我对他的回答稍作修改的版本,它也应该可以解决您遇到的问题。
你可以在这里看到我的原始线程:
我看到您添加了 "This"、"That" 和 "The Other" 作为您的数据源,大概是为了简单地将此问题发布到 SO。请注意,如果您真正的基础数据源可以更改,则在执行 DataBinding 时,您的 class 需要实施 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;
}
这显示了 class、两个属性以及实现 INotifyPropertyChanged 所需的事件和方法。
我有一个 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>
我知道绑定正在工作,因为我在组合框中获得了正确数量的(空白)项目,并且如果我删除 ItemTemplate 可以看到 class 名称。
我一辈子都弄不明白为什么绑定到 属性 名称在这里不起作用,因为它在列表来自控件自己的代码后面时起作用。
我一定有一些其他信息需要添加到 TextBlock 绑定中,但无论我尝试什么 DataContext 或 RelativeSource,我总是得到空白项。
WPF 中的数据绑定仅适用于 public 属性,不适用于字段。您的商品 class 应如下所示:
public class TwoStringClass
{
public string string1 { get; set; }
public string colorHex { get; set; }
}
也就是说,有广泛接受的命名约定,根据该约定,您应该使用 Pascal case 作为 属性 名称,例如String1
和 ColorHex
.
我相信您的问题的答案与我最近发布的一个问题的答案相同,该问题由 StewBob 回答。这是我对他的回答稍作修改的版本,它也应该可以解决您遇到的问题。
你可以在这里看到我的原始线程:
我看到您添加了 "This"、"That" 和 "The Other" 作为您的数据源,大概是为了简单地将此问题发布到 SO。请注意,如果您真正的基础数据源可以更改,则在执行 DataBinding 时,您的 class 需要实施 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;
}
这显示了 class、两个属性以及实现 INotifyPropertyChanged 所需的事件和方法。