在我的wpf应用程序中,我想为listbox条目编写更改的事件处理程序。此条目由组合框和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>
答案 0 :(得分:0)
通常的做法是保留一个标志,表明数据是否有任何变化。 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; }
}