Установка DataContext для ContextMenu из ItemContainer ListView? - PullRequest
4 голосов
/ 05 апреля 2011

Я использую шаблон mvvm, и мне трудно понять, как установить DataContext в ContextMenu из ItemContainerStyle объекта ListView.

Я также не понимаю, почему ListView.ContextMenu и GridView.ColumnHeaderContextMenu ListView могут видеть свойства и команды из моей модели представления, но ContextMenu внутри ListView.ItemContainerStyle не может.

Error

System.Windows.Data Ошибка: 40: Ошибка пути BindingExpression: свойство 'AddMenuItem' не найдено в 'объекте' '' Валюта '(HashCode = 43406546)'. BindingExpression: Path = AddMenuItem; DataItem = 'Валюта' (HashCode = 43406546); целевым элементом является ContextMenu (Name = ''); Свойство target - «ItemsSource» (тип «IEnumerable»)

View

<!-- Removed styles for clarity. -->
<UserControl>

<!-- Add ElementSpy to the UserControl’s rsources -->
<UserControl.Resources>
    <framework:ElementSpy x:Key="spy" />
</UserControl.Resources>

<ListView ItemsSource="{Binding Currency}">

    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="ContextMenu">
                <Setter.Value>
                    <!-- 'AddMenuItem' property not found on 'object' 'Currency' -->
                    <!-- ContextMenu ItemsSource="{Binding AddMenuItem}" / -->

                    <!-- Use the ElementSpy resource -->
                    <ContextMenu ItemsSource="{Binding Source={StaticResource spy}, Path=Element.DataContext.AddMenuItem}" />
                </Setter.Value>
            </Setter>
        </Style>
    </ListView.ItemContainerStyle>

    <ListView.ContextMenu>
        <!-- Works -->
        <ContextMenu ItemsSource="{Binding EditMenuItem}" />
    </ListView.ContextMenu>

    <ListView.View>
        <GridView>
            <GridView.ColumnHeaderContextMenu>
                <!-- Works -->
                <ContextMenu ItemsSource="{Binding SortMenuItem}" />
            </GridView.ColumnHeaderContextMenu>

            <GridViewColumn Header="Code"
                            DisplayMemberBinding="{Binding Path=Code}" />

            <GridViewColumn Header="Description"
                            DisplayMemberBinding="{Binding Path=Description}" />

            <GridViewColumn Header="Exchange Rate"
                            DisplayMemberBinding="{Binding Path=ExchangeRate}" />
        </GridView>

    </ListView.View>

</ListView>
</UserControl>

Код позади

[Export(ViewNames.CurrencyMasterView, typeof(IMasterView))]
[PartCreationPolicy(CreationPolicy.Shared)]
public partial class CurrencyMasterView
    : UserControl, IMasterView
{
    public CurrencyMasterView()
    {
        InitializeComponent();
    }

    [Import]
    private MasterViewModel ViewModel
    {
        set
        {
            this.DataContext = value;
        }
    }
}

ViewModel

[Export(typeof(MasterViewModel))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class MasterViewModel
    : ViewModelBase
{
    [ImportingConstructor]
    public MasterViewModel(IGeneralController generalController, IRegionManager regionManager)
    {
    }

    public ObservableCollection<Currency> Currency
    {
        get
        {
            return this.currency;
        }

        set
        {
            if (this.currency != value)
            {
                this.currency = value;
                this.RaisePropertyChanged(() => this.Currency);
            }
        }
    }

    public List<MenuItemMvvm> SortMenuItem
    {
        get
        {
            return this.CreateSortMenuItem();
        }
    }

    public List<MenuItemMvvm> EditMenuItem
    {
        get
        {
            return this.CreateEditMenuItem();
        }
    }

    public List<MenuItemMvvm> AddMenuItem
    {
        get
        {
            return this.CreateAddMenuItem();
        }
    }

    private List<MenuItemMvvm> CreateEditMenuItem()
    {
        var menu = new List<MenuItemMvvm>();

        menu.Add(new MenuItemMvvm("_Edit")
        {
            Command = this.EditCommand,
            Icon = new Image
            {
                Source = new BitmapImage(new Uri("pack://application:,,,/POS.Modules.Core;component/Resources/Images/16X16/Edit.png"))
            }
        });

        menu.Add(new MenuItemMvvm("_Duplicate")
        {
            Command = this.DuplicateCommand,
            Icon = new Image
            {
                Source = new BitmapImage(new Uri("pack://application:,,,/POS.Modules.Core;component/Resources/Images/16X16/Copy.png"))
            }
        });

        menu.Add(new MenuItemMvvm("_Delete")
        {
            Command = this.DeleteCommand,
            Icon = new Image
            {
                Source = new BitmapImage(new Uri("pack://application:,,,/POS.Modules.Core;component/Resources/Images/16X16/Delete.png"))
            }
        });


        return menu;
    }

    // Other methods removed for clarity
}

Ответы [ 2 ]

2 голосов
/ 22 января 2012

Этот вопрос помог мне разобраться. WPF MenuItem.Command привязка к ElementName приводит к System.Windows.Data Ошибка: 4: Не удается найти источник для привязки со ссылкой

Я обновил источник для всех, кто имеет эту проблему.

Для быстрого ознакомления это то, что я сделал.

Добавьте класс Джоша Смита ElementSpy. Включите привязки ElementName с ElementSpy

Добавьте ElementSpy к источникам UserControl.

<UserControl.Resources>
    <framework:ElementSpy x:Key="spy" />
</UserControl.Resources>

Затем выполните привязку к ресурсу и используйте свойство Element для привязки к DataContext исвойство, которое вы выбираете.

<ContextMenu ItemsSource="{Binding Source={StaticResource spy}, Path=Element.DataContext.AddMenuItem}" />
0 голосов
/ 05 апреля 2011

вы должны использовать RelativeSource и PlacementTarget в вашей привязке. я использую следующий xaml, чтобы добавить контекстное меню для настройки видимости столбцов таблицы данных.

  <DataGrid.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Spalten ein-/ausblenden">                           
                        <StackPanel>
                            <ItemsControl 
                            ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.Columns, Mode=OneWay}"
                            ItemTemplate="{StaticResource Visibility4DataGridColumns}"
                            ></ItemsControl>
                        </StackPanel>
                    </MenuItem>
                </ContextMenu>
            </DataGrid.ContextMenu>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...