Home > Mobile >  How do I get WPF Databinding to notice changes to properties on the model?
How do I get WPF Databinding to notice changes to properties on the model?

Time:04-03

I've created an WPF MVVM app. The ViewModel has properties I can bind to from the View. But one of the properties is basically a model for a json document that has many properties which are either int, string or some other model and so on. In my view I have controls that update these properties. The object updates but no PropertyChanged events fire.

What's a clean way to handle a situation like this? Do I have to create dozens of property accessors in my ViewModel or is there a better way?

Edit for more detail:

Now using Fody per Andy:

In my VM:

public AppModel AppModel { get; set; }

In my Models

public class AppModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public string ApplicationName { get; set; }
    public string ApplicationVersion { get; set; }
}

In my View:

<TextBox Text="{Binding AppModel.ApplicationName, Mode=TwoWay }"/>
<TextBox Text="{Binding AppModel.ApplicationVersion, Mode=TwoWay}"/>

When I start the app and create a new doc I show null in the textbox and the json view.

New Doc

Then I update the textboxes (changing selection a could times to be sure it updated) but nothing fires to call my code to repopulate the JSON text

After entering data

I click the Save button which has code to serialize the object to JSON and I can see my data does exist in the object.

After clicking Save

CodePudding user response:

Since you want to stay MVVM and not add a bunch of properties (which makes sense,since the JSON schema could change). I would use DataTemplates.

I would build a hierarchical collection of PropertyVMs from the JSON and that is bound to the ItemSource of a tree view. Then define a DataTemplate for the view of a single PropertyVM. That template would display the name of the node and the node content. When the content of a node changes, that node can propagate that notification back wherever it needs to go so that the underlying json gets updated.

This gives you a lot of flexibility. You could even define different data templates for different kinds of properties, like a numeric up down for numbers and a date time picker for datetimes.

CodePudding user response:

maybe you can try to use something like my binding in one datagrid, create a object that handle your json and then try to access the properties using Path=yourJsonObject.ID

<DataGrid
                                            x:Name="datagrid_alldata"
                                            Margin="5,0,5,5"
                                            AutoGenerateColumns="False"
                                            CanUserAddRows="False"
                                            CanUserSortColumns="True"
                                            ColumnWidth="auto"
                                            FontSize="15"
                                            IsEnabled="{Binding IsBuildEnable}"
                                            ItemsSource="{Binding Itens, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                            SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                            VerticalScrollBarVisibility="Visible">
                                            <DataGrid.Columns>
                                                <DataGridTextColumn
                                                    Binding="{Binding Path=ID}"
                                                    Header="ID"
                                                    IsReadOnly="True" />
                                                <DataGridTextColumn
                                                    Binding="{Binding Path=Type}"
                                                    Header="{x:Static lang:Resources.VT35}"
                                                    IsReadOnly="True" />
                                                
                                            </DataGrid.Columns>
                                        </DataGrid>

View

private ObservableCollection<PythonModel> _Itens { get; set; }
        public ObservableCollection<PythonModel> Itens
        {
            get
            {
                return _Itens;
            }
            set
            {
                _Itens = value;
                OnPropertyChanged("Itens");
            }
        }
  • Related