0

こんにちは私は次の状況でdatagriddatacontextをコンテキストメニューdatacontextにバインドする方法について質問があります:

         <DataGrid DataContext="{Binding someDataContext}" ItemsSource="{Binding items}">

            <DataGrid.Resources>
                    <ContextMenu  x:Key="LocalViewerMenu" DataContext="{path to DataGrid.DataContext}">
                                <MenuItem Header="Open" Command="{Binding OpenCommand}"/>
                    </ContextMenu>
            </DataGrid.Resources>

            <DataGrid.RowStyle>
                    <Style TargetType="{x:Type DataGridRow}">
                          <Setter Property="ContextMenu" Value="{StaticResource LocalViewerMenu}"/>
                    </Style>
            </DataGrid.RowStyle>

          </DataGrid>

PSコンテキストメニューをDataGridに直接設定できません。行のコンテキストメニューとして表示されます。

前もって感謝します

4

1 に答える 1

2

ここで説明するDataContextProxyの使用を試みることができます。Silverlight 4はWPFのような「RelativeSource」、「AncestorType」をサポートしていないため、DataContextProxyはSilverlight4でネストされたコントロールのDataBindingを簡素化するために使用されます。あなたの場合、コンテキストメニューはビジュアルツリーの一部ではないため、祖先にもアクセスできません。おそらくそれが役立つかもしれません。

編集

はい、私はそれを自分でテストしましたが、DataContextProxy.Loadedイベントが発生することはないため、実際には機能しません(この問題が発生したのは私たちだけではないようです)。それでも、同様のアプローチを使用できます。次の動作を見てください。

public class DataContextProxyBehavior : Behavior<FrameworkElement>
{
    public Object DataSource
    {
        get { return (Object)GetValue(DataSourceProperty); }
        set { SetValue(DataSourceProperty, value); }
    }
    public static readonly DependencyProperty DataSourceProperty =
        DependencyProperty.Register("DataSource", typeof(Object), typeof(DataContextProxy), null);

    protected override void OnAttached()
    {
        base.OnAttached();

        // Binds the target datacontext to the proxy,
        // so whenever it changes the proxy will be updated
        var binding = new Binding();
        binding.Source = this.AssociatedObject;
        binding.Path = new PropertyPath("DataContext");
        binding.Mode = BindingMode.OneWay;
        BindingOperations.SetBinding(this, DataContextProxyBehavior.DataSourceProperty, binding);

        // Add the proxy to the resource collection of the target
        // so it will be available to nested controls
        this.AssociatedObject.Resources.Add(
            "DataContextProxy",
            this
        );
    }
    protected override void OnDetaching()
    {
        base.OnDetaching();

        // Removes the proxy from the Resources
        this.AssociatedObject.Resources.Remove(
            "DataContextProxy"
        );
    }
}

コントロールに設定すると、コントロールのDataContextがコントロールのリソースディクショナリで使用できるようになります。それをテストするために、次のViewModelを作成しました。

public class ViewModel : INotifyPropertyChanged
{
    #region INotifyPropertyChanged values

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion

    public ActionCommand Command { get; set; }

    public List<string> Elements { get; set; }

    public ViewModel()
    {
        this.Elements = new List<string>(){
            "Element1",
            "Element2"
        };

        this.Command = new ActionCommand()
        {
            ExecuteDelegate = this.Execute
        };
    }

    public void Execute(object o)
    {
        MessageBox.Show(o.ToString());
    }
}

そして次のウィンドウ:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="MainWindow"
    Width="525"
    Height="350">
<Window.DataContext>
    <local:ViewModel />
</Window.DataContext>
<Grid Name="LayoutRoot">
    <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Elements}">
        <i:Interaction.Behaviors>
            <local:DataContextProxyBehavior />
        </i:Interaction.Behaviors>
        <DataGrid.RowStyle>
            <Style TargetType="{x:Type DataGridRow}">
                <Setter Property="ContextMenu">
                    <Setter.Value>
                        <ContextMenu>
                            <MenuItem Command="{Binding DataSource.Command,
                                                        Source={StaticResource DataContextProxy}}"
                                      CommandParameter="{Binding}"
                                      Header="Open" />
                        </ContextMenu>
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGrid.RowStyle>
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding}" Header="MyHeader" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>

ビヘイビアーをDataGridにアタッチします。次に、ビヘイビアーはDataGrid.DataContextをそれ自体のDataSourceプロパティにバインドします。次に、DataGridのResourceDictionaryに自分自身を追加します。ContextMenuを定義するときに、静的リソースとして取得できます。

于 2012-11-19T16:31:34.620 に答える