当lostfocus

时间:2015-08-25 14:42:57

标签: c# wpf xaml listbox inotifypropertychanged

我在列表框中有一个文本框,我希望在文本框失去焦点时更新ObservableCollection。我尝试使用我的收集CollectionChanged事件,如本文here中所述,试图解决问题。现在,更新集合的唯一方法是添加或删除列表框中的项目。我是以错误的方式来做这件事的吗?文本框更新集合时我缺少什么?

MainWindow.xaml

<ListBox ItemsSource="{Binding DataLogList,Mode=TwoWay}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Label Content="{Binding DataLogLabel}" Margin="5"/>
                        <TextBox Text="{Binding DataLogName,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Margin="5" Width="150"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

MainViewModel.cs

public MainViewModel()
    { 
        DataLogList = new ObservableCollection<DataLogContent>();
        DataLogList.CollectionChanged += (s, e) =>
        {                
            if (e.NewItems != null)
            {
                foreach (DataLogContent item in e.NewItems)
                {
                    item.PropertyChanged += item_PropertyChanged;
                }
            }

            if (e.OldItems != null)
            {
                foreach (DataLogContent item in e.OldItems)
                {
                    item.PropertyChanged -= item_PropertyChanged;
                }
            }
        };
    }

    void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        NotifyPropertyChanged();
    }

DataLogContent.cs

public class DataLogContent:ViewModelBase
{
    private string dataLogLabel;
    public string DataLogLabel
    { 
        get { return this.dataLogLabel; }
        set
        {
            this.dataLogLabel = value;
            NotifyPropertyChanged();
        }
    }

    private string dataLogName;
    public string DataLogName
    {
        get { return this.dataLogName; }
        set
        {
            this.dataLogLabel = value;
            NotifyPropertyChanged();
        }
    }       
}

1 个答案:

答案 0 :(得分:1)

我基于此工作。我的猜测是你可能会使ObservableCollection内的项目的添加/删除逻辑变得复杂。无需监视属性更改事件,因为每当对象中的属性发生更改时,每个对象都会引发该事件。

这就是我所拥有的:

namespace WpfApplication1
{
    public class MainViewModel : ViewModelBase
    {
        public ObservableCollection<DataLogContent> DataLogList { get; private set; }

        public MainViewModel()
        {
            DataLogList = new ObservableCollection<DataLogContent>();
            DataLogList.Add(new DataLogContent
            {
                DataLogLabel = "Label",
                DataLogName = "Name"
            });

            DataLogList.Add(new DataLogContent
            {
                DataLogLabel = "Label2",
                DataLogName = "Name2"
            });
        }
    }

    public class DataLogContent : ViewModelBase
    {
        private string dataLogLabel;
        public string DataLogLabel
        { 
            get { return this.dataLogLabel; }
            set
            {
                this.dataLogLabel = value;
                OnPropertyChanged("DataLogLabel");
            }
        }

        private string dataLogName;
        public string DataLogName
        {
            get { return this.dataLogName; }
            set
            {
                this.dataLogName = value;
                OnPropertyChanged("DataLogName");
            }
        }       
    }
}

简单的ViewModelBase:

namespace WpfApplication1
{
    public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string property)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(property));
            }
        }
    }
}

的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">
    <ListBox ItemsSource="{Binding DataLogList,Mode=TwoWay}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <Label Content="{Binding DataLogLabel}" Margin="5"/>
                    <TextBox Text="{Binding DataLogName,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Margin="5" Width="150"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Window>