如何工作IViewFor Bind扩展方法?

时间:2015-01-30 10:45:05

标签: wpf mvvm data-binding reactiveui

简单的问题,但我会看到解决方案。或者可能不明白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。

有谁知道,怎么样。绑定工作?

2 个答案:

答案 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
}