wpf 更改选项卡时MahApps更改LeftWindowCommands项

ne5o7dgx  于 2023-03-19  发布在  其他
关注(0)|答案(2)|浏览(237)

我的主窗口中有一个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作为一个“子菜单栏”,所以如果你改变了选定的标签,LeftWindowCommands-Bar也应该改变那里的项目和按钮后面的动作。我已经玩了周围的可见性,但这不是我想要的。
为了更好地理解:

你看到的项目“赠品,Losung,歌曲请求”。这些项目是在我的TabControl。
现在我想改变“子菜单”-项目(在图片中描述),当我选择一个不同的标签,然后赠品。
有人能指导我怎么做吗?
编辑2:最后它与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>

这个工作。设计器显示所有的标签和内容。我如何绑定窗口命令?我想这样的东西:

<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;
    }
o2gm4chl

o2gm4chl1#

理想情况下,您会使用Bindings,但由于您使用的是代码隐藏,这里有一个简单的解决方案(如果您想让它适应MVVM这样的模式,这取决于您):
这段代码的基本功能是:

  • UIElementsList包含所有子菜单(它们可以是任何东西,从简单的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];
        }
    }
}

窗口:

<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,并有任何麻烦,我在这里帮助。

agxfikkp

agxfikkp2#

我认为问题在于您将WindowCommands.ItemSource绑定到WindowCommands对象,而不是控件元素的集合(如按钮、文本块)
下面是我解决方案:
MainWindow.xaml

<mah:MetroWindow x:Class="WpfApp1.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:local="clr-namespace:WpfApp1"
        xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <mah:MetroWindow.LeftWindowCommands>
        <mah:WindowCommands ItemsSource="{Binding Buttons}">
            
        </mah:WindowCommands>
    </mah:MetroWindow.LeftWindowCommands>
    <TabControl x:Name="MainTab" ItemsSource="{Binding TabItems}">
        
    </TabControl>
</mah:MetroWindow>

MainModel.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Media;

namespace WpfApp1
{
    public class MainModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private ObservableCollection<TabCustomItem> mTabItems;

        private ObservableCollection<Button> mButtons;

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public ObservableCollection<TabCustomItem> TabItems
        {
            get { return mTabItems; }
            set 
            { 
                mTabItems = value; 
                OnPropertyChanged("TabItems");
            }
        }

        public ObservableCollection<Button> Buttons
        {
            get { return mButtons; }
            set 
            {
                mButtons = value;
                OnPropertyChanged("Buttons");
            }
        }

        public MainModel() 
        {

            ObservableCollection<Button>  Buttons1 = new ObservableCollection<Button>()
            {
                new Button()
                {
                    Content = "Press Tab #1"
                }
            };
            ObservableCollection<Button>  Buttons2 = new ObservableCollection<Button>()
            {
                new Button()
                {
                    Content = "Press Tab #2"
                }
            };

            ObservableCollection<Button> Buttons3 = new ObservableCollection<Button>()
            {
                new Button()
                {
                    Content = "Press Tab #3"
                }
            };

            Buttons = Buttons1;

            mTabItems = new ObservableCollection<TabCustomItem>
            {
                new TabCustomItem()
                {
                    Header = "Tab #1",
                    ToolItemsSource = Buttons1

                },
                
                new TabCustomItem()
                {
                    Header = "Tab #2",
                    ToolItemsSource = Buttons2
                },

                new TabCustomItem()
                {
                    Header = "Tab #3",
                    ToolItemsSource = Buttons3
                }
            };
        }

        
    }
}

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using MahApps.Metro.Controls;

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : MetroWindow
    {
        private MainModel mMainModel;
        public MainWindow()
        {
            InitializeComponent();
            this.MainTab.SelectionChanged += MainTab_SelectionChanged;
            mMainModel = new MainModel();
            DataContext = mMainModel;
        }

        private void MainTab_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            TabCustomItem ti = (sender as TabControl).SelectedItem as TabCustomItem;
            mMainModel.Buttons = ti.ToolItemsSource;
        }

    }
}

TabCustomItem.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using MahApps.Metro.Controls;

namespace WpfApp1
{
    public class TabCustomItem : TabItem
    {
        public static readonly DependencyProperty ToolItemsSourceProperty = DependencyProperty.Register(nameof(ToolItemsSource), typeof(ObservableCollection<Button>),
                                                                    typeof(TabCustomItem), new PropertyMetadata(null));

        public ObservableCollection<Button> ToolItemsSource
        {
            get { return (ObservableCollection<Button>)GetValue(ToolItemsSourceProperty); }
            set { SetValue(ToolItemsSourceProperty, value); }
        }

    }
}

通过生成更通用的控件集合,您可以将任何控件添加到窗口命令。我不能在数据绑定中引用选定的选项卡,这就是为什么我使用事件处理程序将当前控件集合分配给我绑定到的数据(变量Buttons)
也许重写一个tabcontrol并添加一个绑定变量会使它变得简单(在数据绑定中引用该变量)

相关问题