在 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>
当手动添加按钮作为 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>