如何将List <string>绑定到DependencyProperty

时间:2016-02-03 14:40:05

标签: wpf user-controls

我试图了解DependencyProperty。为此,我想创建一个显示列表的新UserControl

此列表的位置必须作为属性存在于父级中。为此,我只有MainWindow,MainWindowViewModel(这些是父)和UserControl(子)(目前正在使用代码)。

在我的MainWindow中我有

<Grid>
    <uc:RecentList MessageList="{Binding Messages}" />    
</Grid>

背后的代码中
public MainWindow()
{
    InitializeComponent();
    this.DataContext = new MainWindowViewModel();
}

ViewModel

public MainWindowViewModel()
{
    this.Messages = new ObservableCollection<string>();
    this.Messages.Add("Item 1");
    this.Messages.Add("Item 2");
    this.T = "hi";
}

public ObservableCollection<string> Messages { get; set; }

UserControl我有

<Grid>
    <ListView ItemsSource="{Binding MessageList}"></ListView>
    <TextBlock Text="I'm such text to verify this control is showing" />
</Grid>

背后的代码是

public static readonly DependencyProperty MessageListProperty =
DependencyProperty.Register(
"MessageList", typeof(IEnumerable<string>), typeof(RecentList));

public IEnumerable<string> MessageList
{
    get { return (IEnumerable<string>)GetValue(MessageListProperty); }
    set { SetValue(MessageListProperty, value); }
}

我遇到的问题是绑定无效。我可以在输出窗口中看到这个,错误:

  

错误40:BindingExpression路径错误:&#39; MessageList&#39;在&#39; object&#39;上找不到的属性&#39;&#39; MainWindowViewModel&#39; (的HashCode = 26034861)&#39 ;. BindingExpression:路径= MessageList中;的DataItem =&#39; MainWindowViewModel&#39; (的HashCode = 26034861);目标元素是&#39; ListView&#39; (名称=&#39;&#39);目标属性是&#39; ItemsSource&#39; (键入&#39; IEnumerable&#39;)

我理解这个问题,但我很困惑。它正在寻找正确的位置(在MainWindowViewModel中),但它看起来我不明白为什么UserControl正在寻找MessageList中的MainWindowViewModel。我想它是因为那是我设置datacontext的地方但是,我也认为如果我将this.DataContext = this;添加到UserControl的构造函数中那么它就错了(我&#39;我试过了,它也没有工作。

将我的UserControl更新为

<ListView ItemsSource="{Binding MessageList, RelativeSource={RelativeSource Mode=TemplatedParent}}"></ListView>

从某种意义上讲,我没有收到错误消息,但我也看不到结果。

这是我认为在加载应用程序时发生的事情:

  1. MainWindow加载
  2. MainWindow然后会看到UserControl并注意到它需要一个属性。
  3. 在WPF调用UserControl构造函数之前,它会获取属性的值。然后它初始化组件并自动将值推送到UserControl的属性
  4. 我的UserControl如何使用Parents(MainWindow)属性(Messages)

1 个答案:

答案 0 :(得分:4)

UserControl的XAML中的绑定应该将UserControl实例作为其源对象,例如像这样:

<ListView ItemsSource="{Binding MessageList,
    RelativeSource={RelativeSource AncestorType=UserControl}}" />

或者,您可以在UserControl上设置x:Name并使用ElementName绑定:

<UserControl ... x:Name="self">
    ...
    <ListView ItemsSource="{Binding MessageList, ElementName=self}" />
    ...
</UserControl>

除此之外,您通常不应将UserControl的DataContext设置为自身(如DataContext = this;),因为这会有效地阻止从UserControl的父元素继承DataContext,这对于&#是必需的34;外部&#34;绑定工作,如:

<uc:RecentList MessageList="{Binding Messages}" />