gpt4 book ai didi

c# - 在 MVVM 菜单中绑定(bind) HeaderTemplate

转载 作者:行者123 更新时间:2023-12-03 10:35:30 28 4
gpt4 key购买 nike

我有一个 MVVM 样式的菜单,它使用 2 个 View 模型和一个样式完成:

View 模型:

public class CommandViewModel : ViewModelBase
{
private bool _isOpen;
private IEnumerable<object> _items;
private UIElement _placementTarget;



/// <summary>
/// the command itself
/// </summary>
public ICommand Command { get; set; }

/// <summary>
/// parameter object for the command
/// </summary>
public Object CommandParameter { get; set; }

/// <summary>
/// header string for the command, e.g. in menus
/// </summary>
public string Header { get; set; }

/// <summary>
/// oprional Tooltip for the command, e.g. on buttons
/// </summary>
public string Tooltip { get; set; }

/// <summary>
/// optional icon for the command, e.g. on buttons or in menus
/// </summary>
public ControlTemplate Icon { get; set; }


/// <summary>
/// optional item list. e.g. submenu entries.
/// For a submenu set the command to null and fill the Items list with CommandViewModels or other ViewModels you have a template for
/// </summary>
public IEnumerable<Object> Items
{
get { return _items; }
set
{
_items = value;
Command = new RelayCommand<UIElement>((param) =>
{
PlacementTarget = param;
IsOpen = true;
});
}
}


public bool IsOpen
{
get
{
return _isOpen;
}
set
{
_isOpen = value;
RaisePropertyChanged(() => IsOpen);
}
}


public virtual bool IsSeparator { get { return false; } }


public UIElement PlacementTarget
{
get { return _placementTarget; }
set
{
_placementTarget = value;
RaisePropertyChanged(() => PlacementTarget);
}
}
}

分隔器:
public class SeparatorViewModel : CommandViewModel
{
public override bool IsSeparator
{
get { return true; }
}
}

风格:
<Style TargetType="MenuItem" BasedOn="{StaticResource {x:Type MenuItem}}" x:Key="MvvmMenuItemStyle">
<Setter Property="Header" Value="{Binding Header}"/>
<Setter Property="ItemsSource" Value="{Binding Items}"/>
<Setter Property="Command" Value="{Binding Command}"/>
<Setter Property="CommandParameter" Value="{Binding CommandParameter}"/>
<Setter Property="ToolTip" Value="{Binding Tooltip}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsSeparator}" Value="true">
<DataTrigger.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Height="1" Fill="{StaticResource WindowButtonsBackground}" Margin="3,5"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>

用法:
<MenuItem Header="Device" ItemsSource="{Binding DevicesMenu}" Visibility="{Binding IsDevicesMenuVisible, Converter={StaticResource BoolToVisConverter}}">
<MenuItem.Resources>
<Style TargetType="MenuItem" BasedOn="{StaticResource MvvmMenuItemStyle}"/>
</MenuItem.Resources>
</MenuItem>

我将我的(顶部)菜单项的项目绑定(bind)到 CommandViewModels 列表,该列表可以有子项、标题、命令、CommandParameter 等...
IsOpen Prop 用于当我将它与 ContextMenus 一起使用时,这里不是这种情况。

到目前为止,这工作得很好。

现在我想为每个条目添加和图标。我以为我可以在我的样式中添加一个 HeaderTemplate,它显示图标和标题文本,但它不起作用,没有任何显示。

这是我添加到样式中的 HeaderTemplate setter :
    <Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ContentControl Template="{Binding Icon}" Width="26"/>
<TextBlock Text="{Binding Header}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>

注意:我的图标是 ControlTemplate,其中包含 XAML 中的矢量图形,因此我不能使用 MenuItem 的“图标”属性。一旦我将 HeaderTemplate 添加到样式中,菜单条目就不会显示文本和图标。我知道应用了 HeaderTemplate,因为如果我增加图标 ContentControl 的宽度(例如从 26 到 260),我的菜单会变得更宽。这意味着我在 HeaderTemplate 中的绑定(bind)有问题。

有没有人看到问题?

最佳答案

图标和标题的绑定(bind)不在可视化树中,在那里可以轻松访问数据上下文(继承到 VM 的数据上下文所需的数据上下文)和其他项目。绑定(bind)将需要是相对源路径。

这是用于访问具有 VM 的主要数据上下文的近似路径:

Text="{Binding Header, 
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Page}}}"/>

关于c# - 在 MVVM 菜单中绑定(bind) HeaderTemplate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31188560/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com