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>
通常做法是保留一个标志,用于显示数据是否有任何更改。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; }
}