在 MahApps.Metro 中使用数据绑定 ItemsControl 时显示 WindowCommand 的分隔符

Show separators for WindowCommands when using databound ItemsControl in MahApps.Metro

当手动添加按钮作为 window 命令时,分隔符正常显示:

<controls:MetroWindow.RightWindowCommands>
    <controls:WindowCommands ShowSeparators="True">
        <Button Content="Button1" />
        <Button Content="Button2" />
    </controls:WindowCommands>
</controls:MetroWindow.RightWindowCommands>

当尝试使用 ItemsControl 在 XAML 中将按钮动态创建为 window 命令时,我无法正确显示分隔符。除了 margin/padding 之外,按钮本身看起来是正确的,当分隔符固定时,它可能会被固定。

这是我的 XAML:

<controls:MetroWindow.RightWindowCommands>
    <controls:WindowCommands ShowSeparators="True">
        <ItemsControl ItemsSource="{Binding GamesViewModel.Games}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>

            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type entities:Game}">
                    <Button Content="{Binding Name}" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </controls:WindowCommands>
</controls:MetroWindow.RightWindowCommands>

谁能发现我做错了什么?我认为这可能与我正在设置的 ItemsPanel 有关,但我必须这样做才能使按钮水平。也许有一个 style/template 我要覆盖?

这个代码隐藏版本确实有效,但我宁愿通过 XAML:

foreach (Game game in ((MainViewModel)DataContext).GamesViewModel.Games)
    WindowCommands.Items.Add(new Button { Content = game.Name });

我想您已经在不知不觉中注意到了这个问题! WindowCommands 一个 ItemsControl 本身所以只要给它一个 ItemsSource 它就会被排序。

关键是提供它 WindowCommandsItem 而不是您的视图模型(这真的感觉像是 0.13 alpha 系列中的一个错误,我在其中进行了测试,因为如果有记忆的话,它过去在没有这种特殊转换的情况下也能工作。 )

这是我测试过的一些代码:

XAML 位:

<controls:MetroWindow.DataContext>
    <wpfApplication1:ViewModel />
</controls:MetroWindow.DataContext>
<controls:MetroWindow.Resources>
    <DataTemplate DataType="{x:Type wpfApplication1:Model}">
        <Button Content="{Binding Name}" />
    </DataTemplate>
    <wpfApplication1:ModelToWindowCommandsItemConverter x:Key="Converter" />
</controls:MetroWindow.Resources>
<controls:MetroWindow.RightWindowCommands>
    <controls:WindowCommands ItemsSource="{Binding Commands, Converter={StaticResource Converter}}" />
</controls:MetroWindow.RightWindowCommands>

使用的转换器代码:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{ return ((IEnumerable<Model>)value).Select(x => new WindowCommandsItem { Content = x }); }

视图模型:

public class ViewModel
{
    public ObservableCollection<Model> Commands { get; } = new ObservableCollection<Model>
    {
        new Model { Name = "Skyrim" },
        new Model { Name = "Fallout 4" },
        new Model { Name = "Fallout NV" }
    };
}

型号:

public class Model
{
    public string Name { get; set; }
}

结果:

关于@Maverik 的回答,不需要为此使用转换器。只需将 DataTemplate 放在 WindowCommands.ItemTemplate 上即可。

<controls:MetroWindow.RightWindowCommands>
    <controls:WindowCommands ItemsSource="{Binding Commands}">
        <controls:WindowCommands.ItemTemplate>
            <DataTemplate DataType="{x:Type local:Model}">
                <Button Content="{Binding Name}" />
            </DataTemplate>
        </controls:WindowCommands.ItemTemplate>
    </controls:WindowCommands>
</controls:MetroWindow.RightWindowCommands>