简体   繁体   中英

Textbox in listbox not updating when lostfocus

I have a textbox inside of a listbox that I would like to update the ObservableCollection when the textbox loses focus. I tried using my collections CollectionChanged event as described in this post here to try to solve the problem. Right now the only way to update the collection is if I add or remove an item from the listbox. Am I going about this the wrong way? What am I missing for the textbox to update the collection?

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

I have it working based on this. My guess is that you may be over complicating the adding/removing logic of an item inside the ObservableCollection . There's no need to monitor the property changed event, as each object will already raise the event whenever a property within it changes.

Here's what I have:

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM