0

全て、

VM のプロパティにバインドされた CurrentItem プロパティを持つ DataGrid があります。また、新しいオブジェクトを作成し、それを DataGrid の ItemSource がバインドされているコレクションに追加し、CurrentItem を新しいオブジェクトに等しく設定する ICommand もあります。

コードを介して CurrentItem バインディングを変更するときに何らかの理由でコミットが呼び出されないことを除いて、すべてがうまく機能しています。

以下のコードの関連部分を参照してください。

XAML:

<DataGrid ItemSource={Binding} CurrentItem={Binding Path=CurrentItem, UpdateSourceTrigger=PropertyChange, Source={StaticResource VM}}>
    <DataGrid.InputBindings>
        <KeyBinding Command={Binding Path=AddNewItemCommand, UpdateSourceTrigger=PropertyChanged, Source={StaticResource VM}} Key="OemPlus" Modifiers="Control" />
    </DataGrid.InputBindings>
    <DataGrid.Columns>
        ...
    </DataGrid.Columns>
</DataGrid>

仮想マシン:

Class cVM:INotifyPropertyChanged
{

    /*...RaisePropertyChanged(string str) method implimented here to handle PropertyChanged event*/

    private ICommand _AddNewItemCommand; //defined in Constructor.  Adds new item to Collection and sets CurrentItem property.     
    ICommand AddNewItemCommand{ get { return _AddNewItemCommand; } }

    private object _CurrentItem;
    public object CurrentItem
    {
        get
        {
            return _CurrentItem;
        }
        set
        {
            _CurrentItem = value;
            RaisePropertyChanged("CurrentItem");
        }
    }
    /*...*/
}
4

1 に答える 1

0

純粋な MVVM ソリューションではありませんが、問題を解決するために私が行ったことは次のとおりです。

<DataGrid ItemSource={Binding} CurrentItem={Binding Path=CurrentItem, UpdateSourceTrigger=PropertyChange, Source={StaticResource VM}}>
    <DataGrid.InputBindings>
        <KeyBinding Command={Binding Path=AddNewItemCommand, UpdateSourceTrigger=PropertyChanged, Source={StaticResource VM}} CommandParamater={Binding RelativeSource={RelativeSource AncestorType=DataGrid}}" Key="OemPlus" Modifiers="Control" />
    </DataGrid.InputBindings>
    <DataGrid.Columns>
        ...
    </DataGrid.Columns>
</DataGrid>

次に、ICommand (タイプ セーフな RelayCommand です。下部のコードを参照) で次を実行します。

param => { param.SetCurrentValue(DataGrid.CurrentItemProperty, null); param.Dispatcher.DoEvents() /*An extension that pushes a dispather frame with dispatherpriority.background, which forces events to fire that might be in an asynchronious call-stack */; Object obj = new Object(); /*Whatever your Object is, of course */ MyCollection.Add(obj); CurrentItem = obj; }

とにかく、これが次の人に役立つことを願っています。この場合、DoEvents 拡張機能が必要かどうかはわかりませんが、安全のために呼び出しました。また、param については、コンストラクターに Generics を使用する RelayCommand のバージョンを含めたため、私のコードはそれが DataGrid であることを認識しています。

(興味がある場合は、安全なリレーコマンドを入力してください。インターネット上のどこかにあるので、完全な信用はできません)

public class RelayCommand<T> : ICommand
{
    private Action<T> _execute;
    private Predicate<T> _canexecute;

    public RelayCommand(Action<T> execute, Predicate<T> canexecute)
    {
        _execute = execute;
        _canexecute = canexecute;
    }

    public bool CanExecute(object parameter)
    {
        if (_canexecute == null) return false;
        else return _canexecute((T)parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void Execute(object parameter)
    {
        _execute((T)parameter);
    }
}
于 2013-01-17T19:54:32.157 に答える