绑定ListBox中Usercontrol的DependencyProperty
Posted
技术标签:
【中文标题】绑定ListBox中Usercontrol的DependencyProperty【英文标题】:Bind DependencyProperty of Usercontrol in ListBox 【发布时间】:2014-06-22 00:10:38 【问题描述】:我需要 ListBox,其中列出了我的 UserControl。我的用户控件有文本框。所以我想在用户控件的文本框中显示列表子项的属性。我已经尝试了很多使用 DataContext 和 ElementName 的选项 - 它只是不起作用。我只是坚持下去。使其工作的唯一方法是将 UserControl 的 DataContext 绑定删除到自身并更改项目属性名称,使其与 DependencyProperty 名称匹配 - 但我需要在具有不同实体的不同视图模型中重用我的控件,因此几乎不可能使用接近。
有趣的是,如果我将我的 UserControl 更改为 Textbox 并绑定它的 Text 属性 - 一切正常。 Textbox 和我的 UserControl 有什么区别?
所以让我展示一下我的代码。 我已经简化了代码,只显示必要的:
控制 XAML:
<UserControl x:Class="TestControl.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="200"
DataContext="Binding RelativeSource=RelativeSource Self">
<Grid>
<TextBlock Text="Binding Text"/>
</Grid>
</UserControl>
控制 CS:
public partial class MyControl : UserControl
public MyControl()
InitializeComponent();
public string Text
get
return (string)this.GetValue(TextProperty);
set
this.SetValue(TextProperty, value);
public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(MyControl), new propertyMetadata(""));
窗口 XAML:
<Window x:Class="TestControl.MainWindow"
Name="_windows"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestControl"
Title="MainWindow" Height="350" Width="525" >
<Grid Name="RootGrid">
<ListBox ItemsSource="Binding ElementName=_windows, Path=MyList">
<ItemsControl.ItemTemplate >
<DataTemplate >
<local:MyControl Text="Binding Path=Name"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
</Grid>
</Window>
窗口 CS:
public partial class MainWindow : Window
public MainWindow()
_list = new ObservableCollection<Item>();
_list.Add(new Item("Sam"));
_list.Add(new Item("App"));
_list.Add(new Item("H**"));
InitializeComponent();
private ObservableCollection<Item> _list;
public ObservableCollection<Item> MyList
get return _list;
set
public class Item
public Item(string name)
_name = name;
private string _name;
public string Name
get return _name;
set _name = value;
【问题讨论】:
【参考方案1】:这是 XAML 中的一个非常大的问题。问题是当您在用户控件中执行此操作时:
DataContext="Binding RelativeSource=RelativeSource Self"
你改变它的数据上下文,所以在这一行:
<local:MyControl Text="Binding Path=Name"/>
运行时现在将尝试在“MyControl”实例上解析“Name”,而不是在继承的数据上下文(即视图模型)上解析。 (通过检查输出窗口确认这一点——您应该会看到一个绑定错误。)
您可以通过使用RelativeSource
绑定来解决此问题,而不是这样设置用户控件的数据上下文:
<UserControl x:Class="TestControl.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="200"
<Grid>
<TextBlock
Text="Binding Text,RelativeSource=RelativeSource AncestorType=UserControl"
/>
</Grid>
</UserControl>
【讨论】:
"这是 XAML 中的一个非常大的问题。" - 这太轻描淡写了,我花了好几个小时才终于找到答案以上是关于绑定ListBox中Usercontrol的DependencyProperty的主要内容,如果未能解决你的问题,请参考以下文章
WPF 从后面的代码添加的 UserControl 绑定到祖先
实现点击Form区域内除ListBox以外的其他地方,实现ListBox的隐藏,包括UserControl范围内,也包括UserControl之外Form之内