3
votes

Simple question, but I dons see solution. Or may be dont understand how Bind method works. The goal is two way binding between ViewModel and DataContext properties.

    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); }
    }

when I set ViewModel property, I get InvalidCastException "System.String" to "WpfApplication1.MainWindow".

But xaml binding works perfectly.

<MainWindow 
   DataContext="{Binding RelativeSource={RelativeSource Self}, Path=ViewModel, Mode=TwoWay}" ...

full xaml.cs/xaml code is here http://pastebin.com/iCKeNS7R

Where I wrong ?

update: this code:

this.WhenAnyValue(v => v.ViewModel).BindTo(this, v => v.DataContext); this.WhenAnyValue(v => v.DataContext).BindTo(this, v => v.ViewModel);

also works as expected

update 2 Question: Does this.Bind(viewModelParam, ...) ignore viewModelParam argument ??

example^ http://pastebin.com/e2aPaGNc

I bind to _otherViewModel, but when type text into textBox, ViewModel.StrProp changed, not _otherViewModel.

Does anybody know, how this.Bind work ??

2
is this just an example or why you bind the datacontext from your mainwindow to a string?blindmeis
yes, it's for example only, I have "normal" viewmodel class of courseЕвгений Савин
Will: what exackly is wrong? See here (github.com/reactiveui/ReactiveUI.Samples/blob/master/…) only one diff bettween that code and mine is binding/ Code by link use: this.WhenAnyValue(x => x.ViewModel).BindTo(this, x => x.DataContext); I try to use this.Bind(this, v => v.DataContext, v => v.ViewModel); Why their code works, but mine dont ??Евгений Савин

2 Answers

73
votes

Bind doesn't work between ViewModel and DataContext because the types don't match (i.e. I could set DataContext to '4' and now it can't assign that to ViewModel).

However, if you are using ReactiveUI bindings, you don't need DataContext at all, you should just use RxUI bindings everywhere. Please ignore the other answers on this thread that tell you how to do things the wrong way.

0
votes

you can just bind the ViewModel via XAML:

<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>

your viewmodel should implement 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
}