WPF-为列表框中的单个条目设置已更改的事件处理程序

本文关键字:程序 事件处理 设置 单个条 列表 WPF- | 更新日期: 2023-09-27 18:27:22

在我的wpf应用程序中,我想为我的列表框条目编写更改的事件处理程序。此条目由组合框和TimePickers组成。我的列表框链接了一些网络帐户,所以列表框的所有条目都保存在那里。当我尝试保存编辑的条目时,所有条目都会被保存。为了避免这个问题,我想编写更改后的事件处理程序,这样它只会给我更新的条目。如何只为已编辑的条目而不是所有条目编写已更改的事件处理程序。

列表框的xaml:

<ListBox x:Name="listBox1" ItemsSource="{Binding}" Margin="0,131,0,59" ItemTemplateSelector="{StaticResource templateSelector}" SelectionMode="Single" SelectionChanged="listBox1_SelectionChanged">
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <EventSetter Event="MouseDoubleClick" Handler="listBox1_MouseDoubleClick">
                    </EventSetter>
                </Style>
            </ListBox.ItemContainerStyle>
</ListBox>

ListBox包含以下单个条目-

<StackPanel Orientation="Horizontal" Width="596">
                <TextBox Text="{Binding ClientNameBinding,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Background="Yellow" Padding="0" Margin="0" BorderThickness="0" TextWrapping="Wrap" Width="145"/>
                <TextBox Text="{Binding ApplicationNameBinding}" Background="Yellow" Padding="0" Margin="0" BorderThickness="0" TextWrapping="Wrap" Width="90"/>
                <xctk:TimePicker Name="StartPicker" Value="{Binding StartValue, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" Format="Custom" FormatString="hh:mm tt" Background="Yellow" Padding="0" Margin="0" BorderThickness="0" Width="100" EndTime="11:59:0"/>
                <xctk:TimePicker Name="EndPicker" Value="{Binding EndValue, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" Format="Custom" FormatString="hh:mm tt" Background="Yellow" Padding="0" Margin="0" BorderThickness="0" Width="60" EndTime="11:59:0"/>
                <TextBox Text="{Binding TaskNameBinding}" Background="Yellow" Padding="0" Margin="0" BorderThickness="0" TextWrapping="Wrap" Width="71"/>
                <ComboBox x:Name="ProjectComboBox" ItemsSource="{Binding Path=projectList, ElementName=MainWin}" SelectedValuePath="_id" DisplayMemberPath="_name"  SelectedItem="{Binding ProjectNameBindingClass, Mode=OneWayToSource}" Width="130" Background="Yellow" BorderThickness="0"/>
</StackPanel>

WPF-为列表框中的单个条目设置已更改的事件处理程序

通常做法是保留一个标志,用于显示数据是否有任何更改。MVVM样式的示例可以是这样的:

1) 实现INotifyPropertyChanged:的基本视图模型

public abstract class ViewModel : INotifyPropertyChanged
{
    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

2) 列表条目的视图模型。注意,这里是HasChanges属性。当任何其他视图绑定属性发生更改时,HasChanges变为true:

public class MyListEntryViewModel : ViewModel
{        
    public string ClientName
    {
        get { return clientName; }
        set
        {
            if (clientName != value)
            {
                clientName = value;
                OnPropertyChanged("ClientName");
            }
        }
    }
    private string clientName;
    // the rest of bindable properties (ApplicationName, StartPicker, etc.)
    public bool HasChanges
    {
        get { return hasChanges; }
        set
        {
            if (hasChanges != value)
            {
                hasChanges = value;
                OnPropertyChanged("HasChanges");
            }
        }
    }
    private bool hasChanges;
    protected override void OnPropertyChanged(string propertyName)
    {
        base.OnPropertyChanged(propertyName);
        if (propertyName != "HasChanges")
        {
            HasChanges = true;
        }
    }
}

3) 编辑器的视图模型(保存列表条目和添加、删除、保存等命令的东西):

public class MyEditorViewModel : ViewModel
{
    private void SaveChanges()
    {
        var changedItems = Items
            .Where(item => item.HasChanges);
        // send changed items to server
    }
    private bool CanSaveChanges()
    {
        return Items.Any(item => item.HasChanges);
    }
    public MyEditorViewModel()
    {
        SaveChangesCommand = new RelayCommand(SaveChanges, CanSaveChanges);
    }
    public ObservableCollection<MyListEntryViewModel> Items
    {
        get
        {
            return items ?? (items = new ObservableCollection<MyListEntryViewModel>());
        }
    }
    private ObservableCollection<MyListEntryViewModel> items;
    public RelayCommand SaveChangesCommand { get; private set; }
}