简单的问题,但我会看到解决方案。或者可能不明白Bind方法是如何工作的。 目标是ViewModel和DataContext属性之间的双向绑定。
public MainWindow()
{
InitializeComponent();
this.Bind(this, v => v.DataContext, v => v.ViewModel);
}
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(
"ViewModel", typeof (string), typeof (MainWindow));
public string ViewModel
{
get { return (string) GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}
当我设置ViewModel属性时,我得到InvalidCastException" System.String"到" WpfApplication1.MainWindow"。
但是xaml绑定工作得很好。
<MainWindow
DataContext="{Binding RelativeSource={RelativeSource Self}, Path=ViewModel, Mode=TwoWay}" ...
完整的xaml.cs / xaml代码在这里http://pastebin.com/iCKeNS7R
哪里错了?
更新 这段代码:
this.WhenAnyValue(v => v.ViewModel).BindTo(this, v => v.DataContext);
this.WhenAnyValue(v => v.DataContext).BindTo(this, v => v.ViewModel);
也按预期工作
更新2 问题:this.Bind(viewModelParam,...)是否忽略viewModelParam参数??
示例^ http://pastebin.com/e2aPaGNc
我绑定到_otherViewModel,但是当在textBox中键入文本时,ViewModel.StrProp发生了变化,而不是_otherViewModel。
有谁知道,怎么样。绑定工作?
答案 0 :(得分:73)
Bind
在ViewModel和DataContext之间不起作用,因为类型不匹配(即我可以将DataContext设置为'4',现在它无法将其分配给ViewModel。)
但是,如果您使用的是ReactiveUI绑定,则根本不需要需要 DataContext,您应该只在任何地方使用RxUI绑定。请忽略此主题上的其他答案,告诉您如何以错误的方式做事。
答案 1 :(得分:0)
你可以通过XAML绑定ViewModel:
<Window x:Class="YourNameSpace.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModel="clr-namespace:YourNameSpace"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ViewModel:MainViewModel x:Key="MainViewModel"/>
</Window.Resources>
<Grid>
<TextBox Text="{Binding YourProperty, Mode=TwoWay, Source={StaticResource MainViewModel}, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</Window>
你的viewmodel应该实现INotifyPropertyChanged。
public class MainViewModel : INotifyPropertyChanged
{
private string _yourProperty;
public string YourProperty
{
get { return _yourProperty; }
set { _yourProperty = value; OnPropertyChanged("YourProperty"); }
}
public MainViewModel()
{
_yourProperty = "Some string";
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged = delegate { };
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}