将依赖项属性(View)与属性(ViewModel)同步 [英] Synchronizing Dependency Properties (View) with Properties (ViewModel)

查看:162
本文介绍了将依赖项属性(View)与属性(ViewModel)同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人知道我如何将ViewModel中的属性与View中的依赖项属性进行同步?

Does anybody know how I can synchronize my properties, which are in a ViewModel, with my Dependency Properties, which are in the View?

我试图使一个UserControl,然后由WPF窗口(MainWindow.xaml)托管。 UserControl有一个自己的ViewModel,其中包含ICommands和属性。

I am trying to make a UserControl, which will then be hosted by a WPF-Window (MainWindow.xaml). The UserControl has an own ViewModel which contains ICommands and properties.

问题是,我还必须将某些属性返回给MainWindow(.xaml)并进行设置。 。

The problem is, that I also have to return certain properties to the MainWindow(.xaml) and also set them.

当前我的课程看起来像这样:

Currently my classes are looking like that:

MainWindow.xaml

<TextBox Name="tbInput" VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Row="0"></TextBox>
    <local:View x:Name="appEntryView" Pfad="{Binding ElementName=tbInput, Path=Text}" Grid.Row="1" Margin="10"/>

View.xaml

<UserControl x:Class="DependencyProperties.Test"
         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" 
         xmlns:local="clr-namespace:DependencyProperties_Intro"
         x:Name="obj"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">

<Grid>
    <TextBlock Text="{Binding ElementName=obj, Path=Pfad}"/>
</Grid>

View.xaml .cs

public partial class View: UserControl, INotifyPropertyChanged
{

    public String Pfad
    {
        get { return (String)GetValue(PfadProperty); }
        set { SetValue(PfadProperty, value); OnNotifyPropertyChanged("Pfad"); }
    }

    // Using a DependencyProperty as the backing store for Path.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty PfadProperty =
        DependencyProperty.Register("Pfad", typeof(String), typeof(GraphSharpTest), new PropertyMetadata(default(string)));

    public View()
    {
        InitializeComponent();
        this.DataContext = new ViewModel();
        var name = "Pfad";
        var binding = new Binding(name) { Mode = BindingMode.TwoWay };
        this.SetBinding(PfadProperty, binding);
    }
}

ViewModel.cs

public class ViewModel: INotifyPropertyChanged
{
    private String m_Pfad;

    public String Pfad
    {
        get { return m_Pfad; }
        set { m_Pfad = value; OnNotifyPropertyChanged("Pfad"); }
    }


    public void OnNotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(info));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

dependency属性可以正常工作,但是 pfad的setter方法在

The dependency property works fine, but the setter method of "Pfad" in the ViewModel never gets called at all.

预先感谢!

推荐答案

在依赖项属性的CLR属性中提高 PropertyChanged 是一个常见错误。您应该在此处放置任何代码,因为绑定根本不使用任何代码。它们仅用于在代码或XAML中一次设置属性,因此您也不会碰到在那里设置的任何断点。

Raising PropertyChanged in the CLR properties of dependency properties is a common mistake. You should not place any code there as it is not used by bindings at all. They exist merely for setting the property once in code or XAML, thus you also will not hit any breakpoints you set there.

var name = "Pfad";
var binding = new Binding(name) { Mode = BindingMode.TwoWay };
this.SetBinding(PfadProperty, binding);

我认为您想将值转发给视图模型。这将行不通,因为您只能绑定一次属性。现在,您还可以在此处绑定属性:

I take it you want to forward the value to your view-model. This is not going to work as you can only bind the property once. Right now you also bind the property here:

<local:View x:Name="appEntryView" Pfad="{Binding ElementName=tbInput, Path=Text}" Grid.Row="1" Margin="10"/>

您可以在注册时使用相应的元数据来订阅依赖项属性更改,并提供回调,

You could subscribe to the dependency property changes using the respective meta data when registering it, providing a callback, there you could set the value in the view-model.

问题是:视图模型对 View ,如果没有人可以访问数据,那么执行此同步实际上没有任何意义。您可能希望属性可以从外部设置,将 UserControl 像控件一样,丢弃视图模型,或者希望传递视图模型从外部作为 DataContext ,视图直接绑定到它。

The thing is: The view-model is private to the View, there really is no point in doing this synchronization if no-one has access to the data. You probably want the property to be either settable from the outside, treating the UserControl more like a control, discarding the view-model, or you want the view-model to be passed from outside as DataContext, and the view binds directly to it.

在定义 UserControls DataContext 时,请务必小心,将其设置为它会混淆正在发生的事情并导致绑定意外中断。如果要在 UserControl 实例上设置属性,我建议避免使用它。

You need to be careful with explicitly setting the DataContext of UserControls in their definition, as it can obfuscate what is happening and lead to bindings unexpectedly breaking. If you want to set properties on the UserControl instance i would recommend avoiding it.

这篇关于将依赖项属性(View)与属性(ViewModel)同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆