1

私の wpf アプリケーションでは、リスト ボックス エントリの変更されたイベント ハンドラーを記述したいと考えています。このエントリは、コンボボックスと TimePicker で構成されています。私のリストボックスはいくつかのウェブアカウントにリンクされているので、リストボックスのすべてのエントリがそこに保存されました。編集したエントリを保存しようとすると、すべてのエントリが保存されます。この問題を回避するために、変更されたイベント ハンドラーを記述して、更新されたエントリのみが提供されるようにします。すべてのエントリではなく、編集されたエントリのみに対して変更されたイベント ハンドラを記述する方法。

リストボックスの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>
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 に答える