我有一個ListBoxwith 型別的專案,ThemeLayer我想為這些專案添加背景關系選單功能。
ListBoxXAML 定義如下:
<ListBox x:Name="DataLayerList" Grid.Row="2" Grid.ColumnSpan="2" MaxHeight="800"
Width="{Binding ActualWidth, ElementName=PanelGrid}" Margin="0,10,0,0"
ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
HorizontalAlignment="Left" SelectionMode="Extended" IsTextSearchEnabled="True"
ItemsSource="{Binding LayersFiltered, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Image}" Height="16" Width="16" Margin="5,0"/>
<TextBlock Text="{Binding Path=Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}"/>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Add to current / new Map"
Command="{Binding AddServiceFromContext}">
<MenuItem.Icon>
<Image Source="{DynamicResource AddContent16}" Width="16"
RenderOptions.BitmapScalingMode="HighQuality"/>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
的定義AddServiceFromContext在我的 ViewModel 中:
public ICommand AddServiceFromContext
{
get
{
return new RelayCommand(() =>
{
IEnumerable<ThemeLayer> selectedThemeLayers = LayersFiltered.Where(i => i.IsSelected);
}, true);
}
}
一旦我呼叫并可視化背景關系選單,XAML 系結失敗中就會顯示以下錯誤:
在 ThemeLayer 型別的物件上找不到 ThemeLayer AddServiceFromContext MenuItem.Command ICommand AddServiceFromContext 屬性。
也許這個問題的解決方案是微不足道的,這意味著我必須在我的ThemeLayer定義中添加一個屬性,但是看起來如何,這是正確的解決方案嗎?
uj5u.com熱心網友回復:
該AddServiceFromContext命令在也公開LayersFiltered集合的視圖模型中定義。但是,aListBoxItem內部的 aListBox將其DataContext設定為專案源中的相應資料項,即LayersFiltered. 這就是錯誤告訴您的內容,資料背景關系是一個型別的專案,ThemeLayer它不公開屬性AddServiceFromContext。
您需要做的是訪問ListBox(或共享此資料背景關系的任何其他父級)的資料背景關系,它是DockpanePublicDataViewModel并且包含AddServiceFromContext命令。問題是查找父元素的簡單RelativeSource系結將不起作用,因為背景關系選單與ListBox.
在無法訪問資料背景關系的情況下,您可以使用一種解決方法。創建一個系結代理型別,將資料背景關系作為資源間接提供。有關其作業原理的更多資訊,您可以參考Thomas Levesque 的這篇博客文章。
public class BindingProxy : Freezable
{
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
public object Data
{
get => GetValue(DataProperty);
set => SetValue(DataProperty, value);
}
public static readonly DependencyProperty DataProperty = DependencyProperty.Register(
nameof(Data), typeof(object), typeof(BindingProxy));
}
ListBox在資源或其他任何地方創建系結代理的實體,您可以在其中通過Data屬性系結目標資料背景關系。
<ListBox.Resources>
<local:BindingProxy x:Key="DataLayerListBindingProxy" Data="{Binding}"/>
</ListBox.Resources>
然后您可以使用系結代理將命令系結為Source.
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Add to current / new Map"
Command="{Binding Data.AddServiceFromContext, Source={StaticResource DataLayerListBindingProxy}}">
<MenuItem.Icon>
<Image Source="{DynamicResource AddContent16}" Width="16"
RenderOptions.BitmapScalingMode="HighQuality"/>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</Setter.Value>
</Setter>
uj5u.com熱心網友回復:
問題似乎是由于該AddServiceFromContext命令是在 viewModel 中定義的,而不是在用于定義 LayersFiltered串列的類中
可以有2個解決方案:
- 將命令定義到
LayersFiltered類中 - 使用相對背景關系,例如
{Binding RelativeSource = {RelativeSource Mode = FindAncestor, AncestorType = {x: Type UserControl}}, Path = DataContext.AddServiceFromContext}
uj5u.com熱心網友回復:
AddServiceFromContext不是 的DataContext成員MenuItem。如果它是在視圖模型中定義的,您可以將 的Tag屬性系結ListBoxItem到視圖模型,然后將 系結Command到PlacementTargetparent ContextMenu:
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}"/>
<Setter Property="Tag" Value="{Binding DataContext,
RelativeSource={RelativeSource AncestorType=ListBox}}" />
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Add to current / new Map"
Command="{Binding PlacementTarget.Tag.AddServiceFromContext,
RelativeSource={RelativeSource AncestorType=ContextMenu}}">
<MenuItem.Icon>
...
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/446083.html
上一篇:如何在資料觸發器中使用默認樣式?
