正在绑定DataGrid.CurrentItem

本文关键字:CurrentItem DataGrid 绑定 | 更新日期: 2023-09-27 17:53:41

全部,

我有一个DataGrid,它的CurrentItem属性绑定到我的VM中的某个属性。我还有一个ICommand,它创建一个新对象,将其添加到DataGrid的ItemSource绑定到的集合中,并将CurrentItem设置为新对象。

一切都很好,只是由于某些原因,在通过代码更改CurrentItem绑定时没有调用Commits。

请参阅以下代码的相关部分。

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>

VM:

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");
        }
    }
    /*...*/
}

正在绑定DataGrid.CurrentItem

不是一个纯粹的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,我的代码知道它是DataGrid,因为我在构造函数中包含了一个采用泛型的RelayCommand版本

(如果感兴趣,请键入safe relaycommand。在互联网上的某个地方找到,所以不能完全归功于(

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);
    }
}