【问题标题】:How to bind a property of a user control to the MainViewModel and bind its datacontext to its own viewmodel?如何将用户控件的属性绑定到 MainViewModel 并将其数据上下文绑定到自己的视图模型?
【发布时间】:2014-12-06 05:21:09
【问题描述】:

一个新手绑定问题。我的 mainview.xaml 调用了多个用户控件,例如:

  <i:InkRichTextView RichText ="{Binding LastNote}" ... />

其中 RichText 是 InkRichTextView.xaml 用户控件代码隐藏中的依赖属性,LastNote 是 mainviewmodel 的属性。

MainViewModel 通过 App.xaml 中的 DataTemplate 与 MainView 隐式关联,例如:

 <DataTemplate DataType="{x:Type vm:MainViewModel}">
        <v:MainView/>
 </DataTemplate>

我想将用户控件 InkRichTextView 设置为它自己的 ViewModel,其属性保存在 MainViewModel 中,类似于:

<i:InkRichTextView RichText ="{Binding LastNote}" DataContext="{Binding ucFirstControl}" ... />

但是当我这样做时,我的用户控件 InkRichTextView 会丢失 LastNote 的上下文(或在其代码隐藏中失去对其依赖项属性的访问权,或两者兼而有之??)。

如何维护与 LastNote 的 MainViewModel 属性的绑定,同时仍为用户控件提供单独的 DataContext?

(请记住,UserControl 在其代码隐藏中定义了依赖属性)。

感谢您对此的任何帮助。

【问题讨论】:

  • 啊,又过了一周,另一个人试图为他们的 UserControl 创建一个 ViewModel。想知道你为什么在这方面遇到困难吗?这是因为你不应该这样做。想一想——TextBox 有 ViewModel 吗?不,它公开了您将 your ViewModel 绑定到的属性。这就是你的 UserControl 应该做的。更多详情请看这里:stackoverflow.com/…

标签: wpf xaml mvvm data-binding


【解决方案1】:

通过 x:Name 属性为 MainView 命名。然后,对于 RichText 属性,您可以使用如下绑定:RichText={Binding ElementName=mainViewName, Path=DataContext.LastNote}

确实,您可以在 Binding 的 ElementName 属性中使用任何将 MainViewModel 作为其 DataContext 的控件。这可能更容易,因为按名称寻址由 DataTemplate 生成的控件可能很棘手。

以下是一般概念的示例:注意绑定到 ChildName 的 TextBox 如何基于其 DataContext 隐式执行此操作,而它旁边的 TextBox 通过 parentControl(使用 ElementName)绑定到其 DataContext 上的 Name 属性。

xaml:

<Window x:Class="WpfApplication3.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="250">
    <StackPanel x:Name="parentControl" Orientation="Vertical" DataContext="{Binding}">
        <TextBox Text="{Binding Name}"/>
        <StackPanel DataContext="{Binding ChildViewModel}" Margin="10">
            <TextBox Text="{Binding ChildName}"/>
            <TextBox Text="{Binding ElementName=parentControl, Path=DataContext.Name}"/>
        </StackPanel>
    </StackPanel>
</Window>

cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new MainViewModel();
    }

}

public class PropertyNotifier : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propname)
    {
        var propChanged = PropertyChanged;
        if (propChanged != null)
            propChanged(this, new PropertyChangedEventArgs(propname));
    }
}

public class MainViewModel : PropertyNotifier
{
    private string _name = "MainViewModelProperty";
    private ChildViewModel _childViewModel = new ChildViewModel();

    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            OnPropertyChanged("Name");
        }
    }

    public ChildViewModel ChildViewModel
    {
        get { return _childViewModel; }
        set
        {
            _childViewModel = value;
            OnPropertyChanged("ChildViewModel");
        }
    }
}

public class ChildViewModel : PropertyNotifier
{
    private string _childName = "ChildViewModelProperty";

    public string ChildName
    {
        get { return _childName; }
        set
        {
            _childName = value;
            OnPropertyChanged("ChildName");
        }
    }
}

【讨论】:

  • 没用。显示屏为空白。请注意,如果我关闭“DataContext=...”,它会运行良好,但我不能为用户控件使用不同的视图模型。我被继承困住了吗?
  • 这种方法应该是可行的——但细节很微妙,具体取决于对象之间的确切关系。您能否发布一个更完整的示例来重现该问题?我希望能给出一个更完整的答案
  • 我的错误。我没有正确初始化 DataContext 类。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-27
  • 1970-01-01
  • 1970-01-01
  • 2016-03-15
  • 2010-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多