正在将依赖项属性(视图)与属性(ViewModel)同步
本文关键字:属性 ViewModel 同步 视图 依赖 | 更新日期: 2023-09-27 18:27:22
有人知道我如何将ViewModel中的属性与View中的依赖属性同步吗?
我正在尝试创建一个UserControl,然后它将由WPF窗口(MainWindow.xaml)托管。UserControl有一个自己的ViewModel,其中包含ICommands和属性。
问题是,我还必须将某些属性返回到MainWindow(.xaml)并进行设置。
目前我的课程是这样的:
主窗口.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"/>
查看.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>
查看.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属性运行良好,但ViewModel中的setter方法"Pfad"根本不会被调用。
提前感谢!
在依赖属性的CLR属性中引发PropertyChanged
是一个常见的错误。您不应该在那里放置任何代码,因为绑定根本不使用它。它们的存在只是为了在代码或XAML中设置一次属性,因此也不会命中在那里设置的任何断点。
var name = "Pfad";
var binding = new Binding(name) { Mode = BindingMode.TwoWay };
this.SetBinding(PfadProperty, binding);
我认为你想把价值传递给你的视图模型。这是行不通的,因为您只能绑定属性一次。现在你也在这里绑定属性:
<local:View x:Name="appEntryView" Pfad="{Binding ElementName=tbInput, Path=Text}" Grid.Row="1" Margin="10"/>
您可以在注册时使用相应的元数据订阅依赖属性更改,提供回调,在那里您可以在视图模型中设置值。
问题是:视图模型对View
是私有的,如果没有人可以访问数据,那么进行这种同步就没有意义了。您可能希望该属性可以从外部设置,将UserControl
更像一个控件,丢弃视图模型,或者希望视图模型作为DataContext
从外部传递,并且视图直接绑定到它。
您需要小心在UserControls
的定义中显式设置DataContext
,因为这可能会混淆正在发生的事情,并导致绑定意外中断。如果你想在UserControl
实例上设置属性,我建议你不要这样做。