WPF如何设置列表项的值? [英] How does WPF sets a list item value?

查看:101
本文介绍了WPF如何设置列表项的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WPF应用程序(MVVM模式),它具有对字符串和字符串列表的数据绑定:

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

看起来不错,对吧? 但是,当我调试它并将断点设置为setter和getter时,永远不会调用PropertyList setter.但是,PropertyList项0的值具有新值.

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?

推荐答案

当内容更改时,列表不会向GUI发出信号,因此您应始终绑定到WPF中的 ObservableCollections ,使用不用麻烦.

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.

问题很可能是您的_model.PropertyList更新(一种解决方法)(如果两者都使用OC的话)

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

选项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
    }

选项2

我本可以这样做的(只要我了解您想要的),只需将此类用作您的视图的数据上下文即可. 我怀疑这是您定义为_model吗?

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

但是您为什么要绑定到列表中的第一项?清单的重点是什么? 通常,您将PropertyList绑定到项目控件,然后使用双向绑定将Property作为SelectedItem绑定.然后,您可以将文本框绑定到此SelectedItem进行编辑/显示.

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(非常简单)

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

希望有帮助,

欢呼声

Stian

这篇关于WPF如何设置列表项的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆