4

いくつかのメニューオプションのコマンドを使用したコンテキストメニューを備えたデータグリッドがあります。現在、コマンドは一度に1行しか実行できません。メニュー項目を一度クリックすると、選択したすべての行でコマンドを実行できるようにしたいと思います。CanExecuteコマンドを有効/無効にするために使用するので、コマンドを使用したいのですClickが、他にオプションがない場合はを使用します。

これは、一度に1行しか許可しない現在の実装です。

<DataGrid.RowStyle>
   <Style TargetType="{x:Type DataGridRow}">
      <Setter Property="ContextMenu">
         <Setter.Value>
            <ContextMenu>
               <MenuItem Visibility="Visible" 
                         Header="{Binding Path=ApplicationStrings.LaunchItemLabel,
                                          Source={StaticResource ResourceWrapper}}" 
                         Command="{StaticResource launchCommand}" 
                         CommandParameter="{Binding}" />
4

1 に答える 1

2

[DataGridのSelectedItemsプロパティをViewModelプロパティにバインドし、CommandParameterを使用してSelectedItemを返す代わりに、launchCommandでそれにアクセスします。]

編集:お詫びします。SelectedItemsプロパティが読み取り専用であり、変更せずにバインドできないことを忘れていました。

あなたが言及したサムの回避策はその仕事をするべきです、さもなければ以下も同様に働きます:

アイデアは、DataRowのIsSelectedをDataItemのプロパティ(私の例ではMyClass)にバインドし、コマンドハンドラーでコレクションを反復処理して、IsSelectedプロパティを確認することです。

Xaml:

<Window.DataContext>
    <local:ViewModel />
</Window.DataContext>

<Window.Resources>
    <local:BindingProxy x:Key="DataContextProxy"  Data="{Binding}" />
</Window.Resources>

<Grid>
    <DataGrid ItemsSource="{Binding MyRows}" >
        <DataGrid.Resources>
            <Style TargetType="{x:Type DataGridRow}">
                <Setter Property="IsSelected" Value="{Binding IsSelected}" />
                <Setter Property="ContextMenu">
                    <Setter.Value>
                        <ContextMenu>
                            <MenuItem Visibility="Visible" Header="Launch" 
                                      Command="{Binding Data.LaunchCommand, Source={StaticResource DataContextProxy}}" />
                        </ContextMenu>
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGrid.Resources>
    </DataGrid>
</Grid>

ViewModel:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    private ObservableCollection<MyClass> _myRows = new ObservableCollection<MyClass>();
    public ObservableCollection<MyClass> MyRows { get { return _myRows; } set { _myRows = value; OnPropertyChanged("MyRuns"); } }

    private ICommand _launchCommand;
    public ICommand LaunchCommand { get { return _launchCommand; } private set { _launchCommand = value; OnPropertyChanged("LaunchCommand"); } }

    public ViewModel()
    {
        MyRows = new ObservableCollection<MyClass>()
        {
            new MyClass() { Text = "Example Line 1" },
            new MyClass() { Text = "Example Line 2" },
            new MyClass() { Text = "Example Line 3" }

        };

        LaunchCommand = new ActionCommand(Launch);

    }

    private void Launch()
    {
        foreach (var row in MyRows)
        {
            if (row.IsSelected)
            {
                //...
            }
        }
    }
}

public class MyClass : INotifyPropertyChanged
{
    private string _text;
    public string Text { get { return _text; } set { _text = value; OnPropertyChanged("Text"); } }

    private bool _isSelected;
    public bool IsSelected { get { return _isSelected; } set { _isSelected = value; OnPropertyChanged("IsSelected"); } }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

// http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/
public class BindingProxy : Freezable
{
    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    public object Data { get { return (object)GetValue(DataProperty); } set { SetValue(DataProperty, value); } }
    public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

public class ActionCommand : ICommand
{
    public event EventHandler CanExecuteChanged;

    private Action _action;

    public ActionCommand(Action action)
    {
        _action = action;
    }

    public bool CanExecute(object parameter) { return true; }

    public void Execute(object parameter)
    {
        if (_action != null)
            _action();
    }
}
于 2013-03-14T15:13:31.687 に答える