1

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

用于列表框的 xml:

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

1 回答 1

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; }
}
于 2013-08-13T08:00:03.940 回答