wpf 依赖属性绑定用户控件与视图模型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20071236/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dependency property binding usercontrol with a viewmodel
提问by phcoding
Essentially, I have a main window with a user control on it containing a property which is bound to the view model of the main window. The idea is that when the property changes in the user form that by the binding the property in the main window viewmodel will also change. The problem is that this works when the user control has no ViewModel, when I add a simple ViewModel to the user control, the binding no longer works. And as I need to have a ViewModel for my control I need to work out why adding the ViewModel is breaking the binding and how to fix it. Any suggestions welcomed.
本质上,我有一个主窗口,上面有一个用户控件,其中包含一个绑定到主窗口视图模型的属性。这个想法是当用户表单中的属性发生变化时,通过绑定主窗口视图模型中的属性也会发生变化。问题是这在用户控件没有 ViewModel 时有效,当我向用户控件添加一个简单的 ViewModel 时,绑定不再有效。因为我需要有一个 ViewModel 用于我的控件,所以我需要弄清楚为什么添加 ViewModel 会破坏绑定以及如何修复它。欢迎任何建议。
public partial class Control1 : UserControl, INotifyPropertyChanged
{
public Control1()
{
InitializeComponent();
Loaded += Control1_Loaded;
}
void Control1_Loaded(object sender, RoutedEventArgs e)
{
DataContext = new Control1ViewModel();
}
public static DependencyProperty SavedStringProperty = DependencyProperty.Register(
"SavedString", typeof(string), typeof(Control1));
public string SavedString
{
get
{
return (string)GetValue(SavedStringProperty);
}
set
{
SetValue(SavedStringProperty, value);
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void FirePropChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
SavedString = "Hi";
}
}
public class MainWindowViewModel : INotifyPropertyChanged
{
private string _message = "Hi";
public string myMessage
{
get
{
return _message;
}
set
{
_message = value;
FirePropChanged("myMessage");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void FirePropChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
private string _savedString;
public string SavedString
{
get
{
return _savedString;
}
set
{
_savedString = value;
FirePropChanged("SavedString");
}
}
}
xaml (in MainWindow) :
xaml(在主窗口中):
<myCtrl:Control1 SavedString="{Binding Path=SavedString, Mode=TwoWay}"/>
cs (my uc viewmode):
cs(我的 uc 视图模式):
public class Control1ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
}
回答by eran otzap
When your UC has it's own Vm i.e. it's own DataContext , you need to climb up the visual tree and refer to it's parent's (Window) DataContext
当你的 UC 有它自己的 Vm 即它自己的 DataContext 时,你需要爬上可视化树并引用它的父(窗口)DataContext
<myCtrl:Control1 SavedString="{Binding RelativeSource={RelativeSource
AncestorType=Window} Path=DataContext.SavedString, Mode=TwoWay}"/>
回答by JiBéDoublevé
There's another way to write it with an element name:
还有另一种用元素名称编写它的方法:
SavedStrings="{Binding ElementName=uc_name, Path=DataContext.SavedString}"

