У меня есть 3 списка, которые связаны двумя отдельными наблюдаемыми коллекциями того же типа. My ViewModel имеет видимые коллекции, открытые через свойства. Это для некоторой группы перетаскивания, в поле списка источников могут быть элементы, перетаскиваемые в два разных списка. Но я хочу дать пользователю возможность щелкнуть правой кнопкой мыши на элементе listboxitem и установить свойства элемента. Такие вещи, как «Тип», «Имя» и т. Д. Я использую шаблон данных, поскольку я хочу, чтобы все три окна были одинаковыми по функциональности. Это хорошо работает, и я могу вызвать контекстное меню, когда я нажимаю на отдельные элементы без проблем. Моя проблема в том, что у меня есть одно имя FieldType. Это перечисление, которое имеет 4 потенциальных значения. Я не могу, по моей жизни, понять, как связать свойство IsChecked с MenuItem с этим свойством ... функционально в любом случае. Вот что я пытался ....Контекстное меню для listboxitem, связанного с наблюдаемым цветом MVVM style
<DataTemplate x:Key="SFTemplateWithContextMenu">
<TextBlock Text="{Binding Path=FieldName}" ><!--Tag="{Binding DataContext, ElementName=Window}"-->
<TextBlock.ContextMenu>
<ContextMenu >
<ContextMenu.Resources>
<Configurator:EnumToBooleanConverter x:Key="EnumToBooleanConverterc" />
</ContextMenu.Resources>
<MenuItem Header="Rename..." />
<MenuItem Header="Field Type">
<MenuItem.Resources>
<Configurator:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
</MenuItem.Resources>
<MenuItem Header="String" IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=DataContext.FieldType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource EnumToBooleanConverterc}, ConverterParameter={x:Static Configurator:TypeDesc.String}, PresentationTraceSources.TraceLevel=High}"/>
<MenuItem Header="Date" IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=DataContext.FieldType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static Configurator:TypeDesc.Date}}"/>
<MenuItem Header="Barcode" IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=DataContext.FieldType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static Configurator:TypeDesc.BarCode}}" />
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
В коде выше вы можете увидеть на String, Date и штрихкодов MenuItems, что я пытался сделать (надо любить код, работа в процессе) , Моя проблема - это выставленное свойство, которое оно должно вызывать. Я не знаю, как в свойстве ViewModel перейти к элементу в наблюдаемой коллекции, которая соответствует выбранному элементу. У меня есть конвертер значений EnumToBoolean, который будет сидеть на привязке, чтобы получить отметку или нет. Проблема - это свойство, которое устанавливает/получает этот конкретный элемент в наблюдаемой коллекции.
Любые мысли? Нужен больше кода? Мне нужно прояснить что-нибудь? Как близко я? Кстати, код ViewModel написан на VB 2010.
Благодарности Bryce
EDIT: Я попробовал следующее предложение с помощью Ангела ...
<DataTemplate x:Key="SFTemplateWithContextMenu">
<TextBlock x:Name="Field" Text="{Binding Path=FieldName}" >
<TextBlock.ContextMenu PlacementTarget="{Binding ElementName=Field}">
<MenuItem Header="Rename..." />
<MenuItem Header="Field Type">
<MenuItem.Resources>
<Configurator:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
</MenuItem.Resources>
<MenuItem Header="Date" IsCheckable="True" IsChecked="{Binding PlacementTarget.DataContext.FieldType, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static Configurator:TypeDesc.String}, PresentationTraceSources.TraceLevel=High}"/>
</MenuItem>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
Но это дает мне ошибка, которая говорит ... Невозможно установить свойства элементов свойств. Не уверен, что это проблема TextBlox vs TextBox? Вы использовали TextBox в своем примере ... я предполагаю, что ваш код будет делать то же самое. Так я тогда попробовал следующее ...
<DataTemplate x:Key="SFTemplateWithContextMenu">
<TextBlock x:Name="Field" Text="{Binding Path=FieldName}" ><!--Tag="{Binding DataContext, ElementName=Window}"-->
<TextBlock.ContextMenu>
<ContextMenu PlacementTarget="{Binding ElementName=Field}" >
<MenuItem Header="Rename..." />
<MenuItem Header="Field Type">
<MenuItem.Resources>
<Configurator:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
</MenuItem.Resources>
<MenuItem Header="Date" IsCheckable="True" IsChecked="{Binding PlacementTarget.DataContext.FieldType, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static Configurator:TypeDesc.String}, PresentationTraceSources.TraceLevel=High}"/>
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
Но это вызывает обязательные ошибки ... System.Windows.Data Ошибка: 4: Не удается найти источник для связывания со ссылкой «ELEMENTNAME = Поле». BindingExpression: (нет пути); DataItem = NULL; целевой элемент - «ContextMenu» (Name = ''); target property - «PlacementTarget» (тип «UIElement»)
Таким образом, похоже, что привязка не работает. Есть предположения?
Поскольку TextBox генерируется с помощью DataTemplate от привязки к наблюдаемой коллекции все они будут иметь тот же х: Name. Нужно ли уникальное имя x: Name? Разве это не запутается в отношении того, к кому нужно привязываться, если все они имеют одно и то же имя? –
Имена уникально ** ограничены ** в WPF, поэтому я думаю, что подход 'ElementName' будет работать. См. Эту ссылку на namescoping ... http://msdn.microsoft.com/en-us/library/ms746659.aspx –
Я обновил свое сообщение, чтобы отразить текущие проблемы, которые у меня возникают с вашим предлагаемым решением ... может вы, пожалуйста, взгляните и сообщите мне, если это имеет смысл для вас? –