0

全部,

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

一切都很好,除了由于某种原因在通过代码更改 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 扩展,但为了安全起见,我称之为。此外,对于参数,我的代码知道它是 DataGrid,因为我在构造函数中包含了一个采用泛型的 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);
    }
}
于 2013-01-17T19:54:32.157 回答