MahApps 在更改选项卡时更改 LeftWindowCommands 项
MahApps Change LeftWindowCommands Items when changing the tab
我的 MainWindow 中有一个 tabControl 和一个可用的 LeftWindowCommand
<Controls:MetroWindow.LeftWindowCommands>
<Controls:WindowCommands >
<Button x:FieldModifier="public" x:Name="btnOpenBanMenu" Click="btnOpenBanMenu_Click">
<StackPanel Orientation="Horizontal">
<Rectangle Width="20"
Height="20"
Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type Button}}}">
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill" Visual="{StaticResource bans}" />
</Rectangle.OpacityMask>
</Rectangle>
<TextBlock Margin="4 0 0 0"
VerticalAlignment="Center"
Text="Bans"/>
</StackPanel>
</Button>
</Controls:WindowCommands>
</Controls:MetroWindow.LeftWindowCommands>
一切都很好。
但是现在我想将 LeftWindowCommand 用作 "Sub-Menu-Bar",因此如果您更改 selected 选项卡,LeftWindowCommands-Bar 也应该更改那里的项目和按钮后面的操作。
我试过能见度,但这不是我想要的。
为了更好地理解:
您看到了项目 "Giveaway, Losung, Songrequest"。
这些项目在我的 TabControl 中。
现在我想在 select 一个不同的标签然后赠品时更改 "Sub Menu"-项目(如图所示)。
谁能指导我,怎么做?
EDIT2:最后它可以与 MVVM 一起使用,但我仍然不知道如何绑定 LeftWindowCommands。
主模型:
class MainModel
{
public string Header { get; set; }
public MahApps.Metro.Controls.MetroContentControl Content { get; set; }
public MahApps.Metro.Controls.WindowCommands LeftWindowCommands { get; set; }
}
主视图模型:
class MainViewModel : BaseViewModel
{
private ObservableCollection<Model.MainModel> _tabItems;
public ObservableCollection<Model.MainModel> tabItems
{
get { return _tabItems; }
set
{
_tabItems = value;
OnPropertyChanged("tabItems");
}
}
public MainViewModel()
{
_tabItems = new ObservableCollection<Model.MainModel>()
{
new Model.MainModel
{
Header = "Giveaway",
Content = new Controls.ucGiveaway(),
LeftWindowCommands = LeftWindowCommandsGiveaway()
},
... etc
};
}
private MahApps.Metro.Controls.WindowCommands LeftWindowCommandsGiveaway()
{
MahApps.Metro.Controls.WindowCommands command = new MahApps.Metro.Controls.WindowCommands();
command.Items.Add(
new Button { Content = "MyButton #1", Foreground = Brushes.Red });
return command;
}
}
数据上下文:
<Controls:MetroWindow.DataContext>
<ViewModels:MainViewModel/>
</Controls:MetroWindow.DataContext>
选项卡控件:
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding Header}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<Controls:MetroContentControl
Content="{Binding Content}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
这行得通。设计器显示所有选项卡和内容。
我如何绑定 WindowCommands?
我想要这样的东西:
<Controls:MetroWindow.LeftWindowCommands>
<Controls:WindowCommands ItemsSource="{Binding LeftWindowCommands}">
</Controls:WindowCommands>
</Controls:MetroWindow.LeftWindowCommands>
此外,我希望能够在我的 MainViewModel 中添加多个按钮。类似于:
private MahApps.Metro.Controls.WindowCommands LeftWindowCommandsGiveaway()
{
MahApps.Metro.Controls.WindowCommands command = new MahApps.Metro.Controls.WindowCommands();
command.Items.Add(
new Button { Content = "MyButton #1", Foreground = Brushes.Red });
command.Items.Add(
new Button { Content = "MyButton #2", Foreground = Brushes.Red });
return command;
}
理想情况下,您会使用绑定,但由于您使用的是代码隐藏,这里有一个简单的解决方案(如果您想使其适应 MVVM 等模式,则由您决定):
基本上这段代码的作用是:
有一个 List
of UIElements
包含所有子菜单(它们可以是任何东西,从简单的 Button
到 StackPanel
充满元素)。
- 重要提示:列表中的项目必须排序,这意味着索引 0 => 选项卡索引 0 的子菜单。
在WindowCommands
里面有一个TransitioningContentControl
,负责包含子菜单。
每次选定的选项卡更改时,我都会将 List
的第 n 个位置加载到 TransitioningContentControl
(n 是 TabControl
的选定索引)。
输出:
下面是我在示例中使用的代码,您可以对其进行调整:
代码隐藏:
public partial class MainWindow : MetroWindow
{
public List<UIElement> LeftWindowCommands { get; private set; }
public MainWindow()
{
InitializeComponent();
LeftWindowCommands = new List<UIElement>();
var StackPanelForTab1 = new StackPanel() { Orientation = Orientation.Horizontal };
var StackPanelForTab2 = new StackPanel() { Orientation = Orientation.Horizontal };
var StackPanelForTab3 = new StackPanel() { Orientation = Orientation.Horizontal };
// You can add as many children as you want
StackPanelForTab1.Children.Add(new Button { Content = "MyButton #1", Foreground = Brushes.Red });
StackPanelForTab2.Children.Add(new Button { Content = "MyButton #2", Foreground = Brushes.Black });
StackPanelForTab3.Children.Add(new Button { Content = "MyButton #3", Foreground = Brushes.Blue });
// MUST add items in the right order on the list
// MUST have the sabe amount of tabs on the TabControl and items on the list
LeftWindowCommands.Add(StackPanelForTab1);
LeftWindowCommands.Add(StackPanelForTab2);
LeftWindowCommands.Add(StackPanelForTab3);
}
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.Source is TabControl)
{
MyContentControl.Content = LeftWindowCommands[MyTabControl.SelectedIndex];
}
}
}
Window:
<Controls:MetroWindow x:Class="WpfTests.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:local="clr-namespace:WpfTests"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Controls:MetroWindow.LeftWindowCommands>
<Controls:WindowCommands>
<Controls:TransitioningContentControl x:Name="MyContentControl" />
</Controls:WindowCommands>
</Controls:MetroWindow.LeftWindowCommands>
<TabControl SelectionChanged="TabControl_SelectionChanged" x:Name="MyTabControl" >
<TabItem Header="Tab #1">
<Label>#1</Label>
</TabItem>
<TabItem Header="Tab #2">
<Label>#2</Label>
</TabItem>
<TabItem Header="Tab #3">
<Label>#3</Label>
</TabItem>
</TabControl>
</Controls:MetroWindow>
你需要这个:
using MahApps.Metro.Controls;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
如果您尝试使其适应 MVVM 并遇到任何问题,我会在这里提供帮助。
我的 MainWindow 中有一个 tabControl 和一个可用的 LeftWindowCommand
<Controls:MetroWindow.LeftWindowCommands>
<Controls:WindowCommands >
<Button x:FieldModifier="public" x:Name="btnOpenBanMenu" Click="btnOpenBanMenu_Click">
<StackPanel Orientation="Horizontal">
<Rectangle Width="20"
Height="20"
Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type Button}}}">
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill" Visual="{StaticResource bans}" />
</Rectangle.OpacityMask>
</Rectangle>
<TextBlock Margin="4 0 0 0"
VerticalAlignment="Center"
Text="Bans"/>
</StackPanel>
</Button>
</Controls:WindowCommands>
</Controls:MetroWindow.LeftWindowCommands>
一切都很好。 但是现在我想将 LeftWindowCommand 用作 "Sub-Menu-Bar",因此如果您更改 selected 选项卡,LeftWindowCommands-Bar 也应该更改那里的项目和按钮后面的操作。 我试过能见度,但这不是我想要的。
为了更好地理解:
您看到了项目 "Giveaway, Losung, Songrequest"。 这些项目在我的 TabControl 中。
现在我想在 select 一个不同的标签然后赠品时更改 "Sub Menu"-项目(如图所示)。
谁能指导我,怎么做?
EDIT2:最后它可以与 MVVM 一起使用,但我仍然不知道如何绑定 LeftWindowCommands。
主模型:
class MainModel
{
public string Header { get; set; }
public MahApps.Metro.Controls.MetroContentControl Content { get; set; }
public MahApps.Metro.Controls.WindowCommands LeftWindowCommands { get; set; }
}
主视图模型:
class MainViewModel : BaseViewModel
{
private ObservableCollection<Model.MainModel> _tabItems;
public ObservableCollection<Model.MainModel> tabItems
{
get { return _tabItems; }
set
{
_tabItems = value;
OnPropertyChanged("tabItems");
}
}
public MainViewModel()
{
_tabItems = new ObservableCollection<Model.MainModel>()
{
new Model.MainModel
{
Header = "Giveaway",
Content = new Controls.ucGiveaway(),
LeftWindowCommands = LeftWindowCommandsGiveaway()
},
... etc
};
}
private MahApps.Metro.Controls.WindowCommands LeftWindowCommandsGiveaway()
{
MahApps.Metro.Controls.WindowCommands command = new MahApps.Metro.Controls.WindowCommands();
command.Items.Add(
new Button { Content = "MyButton #1", Foreground = Brushes.Red });
return command;
}
}
数据上下文:
<Controls:MetroWindow.DataContext>
<ViewModels:MainViewModel/>
</Controls:MetroWindow.DataContext>
选项卡控件:
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding Header}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<Controls:MetroContentControl
Content="{Binding Content}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
这行得通。设计器显示所有选项卡和内容。 我如何绑定 WindowCommands? 我想要这样的东西:
<Controls:MetroWindow.LeftWindowCommands>
<Controls:WindowCommands ItemsSource="{Binding LeftWindowCommands}">
</Controls:WindowCommands>
</Controls:MetroWindow.LeftWindowCommands>
此外,我希望能够在我的 MainViewModel 中添加多个按钮。类似于:
private MahApps.Metro.Controls.WindowCommands LeftWindowCommandsGiveaway()
{
MahApps.Metro.Controls.WindowCommands command = new MahApps.Metro.Controls.WindowCommands();
command.Items.Add(
new Button { Content = "MyButton #1", Foreground = Brushes.Red });
command.Items.Add(
new Button { Content = "MyButton #2", Foreground = Brushes.Red });
return command;
}
理想情况下,您会使用绑定,但由于您使用的是代码隐藏,这里有一个简单的解决方案(如果您想使其适应 MVVM 等模式,则由您决定):
基本上这段代码的作用是:
有一个
List
ofUIElements
包含所有子菜单(它们可以是任何东西,从简单的Button
到StackPanel
充满元素)。- 重要提示:列表中的项目必须排序,这意味着索引 0 => 选项卡索引 0 的子菜单。
在
WindowCommands
里面有一个TransitioningContentControl
,负责包含子菜单。每次选定的选项卡更改时,我都会将
List
的第 n 个位置加载到TransitioningContentControl
(n 是TabControl
的选定索引)。
输出:
下面是我在示例中使用的代码,您可以对其进行调整:
代码隐藏:
public partial class MainWindow : MetroWindow
{
public List<UIElement> LeftWindowCommands { get; private set; }
public MainWindow()
{
InitializeComponent();
LeftWindowCommands = new List<UIElement>();
var StackPanelForTab1 = new StackPanel() { Orientation = Orientation.Horizontal };
var StackPanelForTab2 = new StackPanel() { Orientation = Orientation.Horizontal };
var StackPanelForTab3 = new StackPanel() { Orientation = Orientation.Horizontal };
// You can add as many children as you want
StackPanelForTab1.Children.Add(new Button { Content = "MyButton #1", Foreground = Brushes.Red });
StackPanelForTab2.Children.Add(new Button { Content = "MyButton #2", Foreground = Brushes.Black });
StackPanelForTab3.Children.Add(new Button { Content = "MyButton #3", Foreground = Brushes.Blue });
// MUST add items in the right order on the list
// MUST have the sabe amount of tabs on the TabControl and items on the list
LeftWindowCommands.Add(StackPanelForTab1);
LeftWindowCommands.Add(StackPanelForTab2);
LeftWindowCommands.Add(StackPanelForTab3);
}
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.Source is TabControl)
{
MyContentControl.Content = LeftWindowCommands[MyTabControl.SelectedIndex];
}
}
}
Window:
<Controls:MetroWindow x:Class="WpfTests.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:local="clr-namespace:WpfTests"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Controls:MetroWindow.LeftWindowCommands>
<Controls:WindowCommands>
<Controls:TransitioningContentControl x:Name="MyContentControl" />
</Controls:WindowCommands>
</Controls:MetroWindow.LeftWindowCommands>
<TabControl SelectionChanged="TabControl_SelectionChanged" x:Name="MyTabControl" >
<TabItem Header="Tab #1">
<Label>#1</Label>
</TabItem>
<TabItem Header="Tab #2">
<Label>#2</Label>
</TabItem>
<TabItem Header="Tab #3">
<Label>#3</Label>
</TabItem>
</TabControl>
</Controls:MetroWindow>
你需要这个:
using MahApps.Metro.Controls;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
如果您尝试使其适应 MVVM 并遇到任何问题,我会在这里提供帮助。