jadok
jadok

Reputation: 113

wpf mvvm binding to sub viewmodel.property

I made an example as simple as possible.
I have a class ViewModelMain whose will implement several viewmodels.
I am trying to bind my slider value on a viewmodel in my ViewModelMain. Here my code:

MainWindow.xaml.cs
I set the datacontext here, don't know if it is realy a good idea.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        VMMain vm = new VMMain();
        this.DataContext = vm;
    }
}

MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Slider Height="23"  Name="page_slider"  Width="100" Value="{Binding Path=p.NbrLine}"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Minimum="0" Maximum="10"/>
    <TextBox Text="{Binding Value, ElementName=page_slider, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Height="28" HorizontalAlignment="Stretch"  Name="Voiture1Label" VerticalAlignment="Stretch" Margin="0,110,0,172"></TextBox>
</Grid></Window>

ViewModelMain.cs ViewModelBase : the class which implement the INotifyPropertyChanged ModelPage : my model MyPage : my sub viewmode which is the viewmodel of ModelPage ViewModelMain : my final viewmodel which will implement more viewmodel

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
}

public class ModelPage
{
    public int NbrLine { get; set; }
    public int NbrCapsLock { get; set; }
}

public class MyPage : ViewModelBase
{
    private ModelPage _model;

    public MyPage(ModelPage m)
    {
        _model = m;
    }
    public int NbrLine
    {
        get { return (_model.NbrLine); }
        set
        {
            if (_model.NbrLine == value) return;
            _model.NbrLine = value;
            OnPropertyChanged("NbrLine");
        }
    }

    public int NbrCapsLock
    {
        get { return (_model.NbrCapsLock); }
        set
        {
            if (_model.NbrCapsLock == value) return;
            _model.NbrCapsLock = value;
            OnPropertyChanged("NbrCapsLock");
        }
    }
}

public class ViewModelMain
{
    public MyPage p;

    public ViewModelMain()
    {
        p = new MyPage(new ModelPage(){NbrLine = 5, NbrCapsLock = 1});
    }
}

when i launch it, my slider is still on 0 doesn't understand why it is not on 5.

Upvotes: 1

Views: 1486

Answers (2)

Dmitry
Dmitry

Reputation: 2052

Actually you chould transform p into property like that. WPF can not bind to simple attributes.

public class ViewModelMain
{
    public MyPage p { get; set; }

    public ViewModelMain()
    {
        p = new MyPage(new ModelPage() { NbrLine = 5, NbrCapsLock = 1 });
    }
}

Upvotes: 2

Adi Lester
Adi Lester

Reputation: 25201

p is a field, not a property. You should only bind to properties:

public MyPage p { get; set; }

Upvotes: 3

Related Questions