How does WPF sets a list item value?

爱⌒轻易说出口 提交于 2019-12-12 03:31:07

问题


I have a WPF application (MVVM pattern) with databinding to strings and list of strings:

public string Property
{
    get { return _model.property; }
    set
    {
        if (value == _model.property)
        {
            return;
        }
        _model.property= value;
        base.NotifyPropertyChanged();
    }
}        

public List<string> PropertyList
{
    get { return _model.PropertyList; }
    set
    {
        if (value == _model.PropertyList)
        {
            return;
        }
        _model.PropertyList= value;
        base.NotifyPropertyChanged();
    }
}

My binding looks like this:

<TextBox Text="{Binding Path=Property, 
                Mode=TwoWay,         
                UpdateSourceTrigger=PropertyChanged}"
>

<TextBox Text="{Binding Path=PropertyList[0], 
                Mode=TwoWay,         
                UpdateSourceTrigger=PropertyChanged}"
>

Looks fine, right? But when i debug it, and set breakpoints to the setter and getter, the PropertyList setter would be never called. However the value of the PropertyList item 0 have the new value.

So how the binding of lists or exactly one item works?


回答1:


List does not signal the GUI when content changes, so you should always bind to ObservableCollections in WPF, which does that for you with no hassle.

The issue is likely your _model.PropertyList update, one way to handle it, if both are using OC's

Option 1

    public ObservableCollection<String> PropertyList
    {
        get { return propertyList; }
        set
        {
            if (Equals(value, propertyList)) return;
            propertyList = value;
            propertyList.CollectionChanged += propertyList_CollectionChanged; // I Hate this
            OnPropertyChanged("PropertyList");
        }
    }

    void propertyList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        OnPropertyChanged("PropertyList"); // when the collection changes signal gui
    }

Option 2

I would have done it this way(given I understand what you want), just use this class as datacontext for your view. I suspect this is what you define as _model?

public class YourViewModel : INotifyPropertyChanged // your ViewModelBase goes here :)
{
    private ObservableCollection<string> propertyList = new ObservableCollection<string>();
    private string property;
    public ObservableCollection<String> PropertyList
    {
        get { return propertyList; }
        set
        {
            if (Equals(value, propertyList)) return;
            propertyList = value;
            OnPropertyChanged("PropertyList");
        }
    }
    public String Property
    {
        get { return property; }
        set
        {
            if (value == property) return;
            property = value;
            OnPropertyChanged("Property");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator] // Comment out if no R#
    protected virtual void OnPropertyChanged(string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

But why are you binding to the first item in the list there? What's the point of the list? Typically you would bind the PropertyList to an items control and bind Property as a SelectedItem with a twoway binding. Then you could bind your textbox to this SelectedItem for editing/display.

IE (very simple )

<Grid>        
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <ListBox Grid.Row="0"  ItemsSource="{Binding PropertyList}" SelectedItem="{Binding Path=Property, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    <TextBox Grid.Row="1" Text="{Binding Path=Property, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>          
</Grid>

Hope it helps,

Cheers

Stian



来源:https://stackoverflow.com/questions/25456376/how-does-wpf-sets-a-list-item-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!