首页 > 解决方案 > C# WPF XAML 工具包,单击按钮切换视图

问题描述

在 XAML Toolkit 中使用 Material Design。我有带抽屉的主窗口,其中包含用户控件列表(应用程序选项卡)。当我单击它们时 - 应用程序选项卡在此控件之间切换。我想在窗口中添加一个按钮,当我单击它时,我也想在选项卡之间切换。你可以在这里看到我的代码的重要部分:

    <materialDesign:DialogHost Identifier="RootDialog" SnackbarMessageQueue="{Binding ElementName=MainSnackbar, Path=MessageQueue}">
    <materialDesign:DrawerHost IsLeftDrawerOpen="{Binding ElementName=MenuToggleButton, Path=IsChecked}">
        <materialDesign:DrawerHost.LeftDrawerContent>
            <DockPanel MinWidth="212">
                <ToggleButton Style="{StaticResource MaterialDesignHamburgerToggleButton}" 
                                DockPanel.Dock="Top"
                                HorizontalAlignment="Right" Margin="16"
                                IsChecked="{Binding ElementName=MenuToggleButton, Path=IsChecked, Mode=TwoWay}" />
                <ListBox x:Name="DemoItemsListBox" Margin="0 16 0 16" SelectedIndex="0"                         
                         ItemsSource="{Binding DemoItems}"
                         PreviewMouseLeftButtonUp="UIElement_OnPreviewMouseLeftButtonUp">
                    <ListBox.ItemTemplate>
                        <DataTemplate DataType="helpers:DemoItem">
                            <TextBlock Text="{Binding Name}" Margin="32 0 32 0" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </DockPanel>
        </materialDesign:DrawerHost.LeftDrawerContent>
        <DockPanel>
            <materialDesign:ColorZone Padding="16" materialDesign:ShadowAssist.ShadowDepth="Depth2"
                                        Mode="PrimaryDark" DockPanel.Dock="Top">
                <DockPanel>
                    <ToggleButton Style="{StaticResource MaterialDesignHamburgerToggleButton}" IsChecked="False"
                                    x:Name="MenuToggleButton"/>

                    <materialDesign:PopupBox x:Name="popupBox">
                        <TextBlock>Check me please</TextBlock>
                    </materialDesign:PopupBox>
                    <CheckBox x:Name="LizenzeCheckBox" DockPanel.Dock="Right" Style="{StaticResource MaterialDesignCheckBox}" Tag="False">
                        <CheckBox.IsChecked>
                            <Binding Path="Tag" RelativeSource="{RelativeSource Self}">
                                <Binding.ValidationRules>
                                    <helpers:IsCheckedValidationRule />
                                </Binding.ValidationRules>
                            </Binding>
                        </CheckBox.IsChecked>CheckBox text</CheckBox>
                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="22">My App</TextBlock>
                </DockPanel>
            </materialDesign:ColorZone>
            <Button x:Name="TheBUTTON" Click="Button_Click">Ckicc</Button>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>

                <ScrollViewer Grid.Row="1" 
                              HorizontalScrollBarVisibility="{Binding ElementName=DemoItemsListBox, Path=SelectedItem.HorizontalScrollBarVisibilityRequirement}"
                              VerticalScrollBarVisibility="{Binding ElementName=DemoItemsListBox, Path=SelectedItem.VerticalScrollBarVisibilityRequirement}" 
                              Padding="{Binding ElementName=DemoItemsListBox, Path=SelectedItem.MarginRequirement}">
                    <ContentControl Content="{Binding ElementName=DemoItemsListBox, Path=SelectedItem.Content}" />
                </ScrollViewer></Grid>

这是我的主窗口 xaml 代码,如您所见,我将 ListBox 值从 viewModel 绑定到 DemoItem[] 数组。“TheButton” onclick 事件是我想用于标签切换的事件。

我的主窗口视图模型是:

public class MainWindowViewModel
{
    public DemoItem[] DemoItems { get; }

    public MainWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue)
    {
        if (snackbarMessageQueue == null) throw new ArgumentNullException(nameof(snackbarMessageQueue));
        DemoItems = new[]
        {
            new DemoItem("Tab1", new Tab1()),
            new DemoItem("Tab2", new Tab2()),
            new DemoItem("Tab3", new Tab3()),
        };
    }
}

MainWindow.cs 是:

 public partial class MainWindow : Window
{
    public static Snackbar Snackbar;

    public MainWindow()
    {
        InitializeComponent();

        Task.Factory.StartNew(() =>
        {
            Thread.Sleep(1000);
        }).ContinueWith(t =>
        {
            MainSnackbar.MessageQueue.Enqueue("Welcome to my app");
        }, TaskScheduler.FromCurrentSynchronizationContext());

        DataContext = new MainWindowViewModel(MainSnackbar.MessageQueue);

    }

    private void UIElement_OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        //until we had a StaysOpen glag to Drawer, this will help with scroll bars
        var dependencyObject = Mouse.Captured as DependencyObject;
        while (dependencyObject != null)
        {
            if (dependencyObject is ScrollBar) return;
            dependencyObject = VisualTreeHelper.GetParent(dependencyObject);
        }
        MenuToggleButton.IsChecked = false;
    } 

    private void Button_Click(object sender, RoutedEventArgs e)
    {
      //what to do here?
    }
}

DemoItem 类是:

public class DemoItem : INotifyPropertyChanged
{
    private string _name;
    private object _content;
    private ScrollBarVisibility _horizontalScrollBarVisibilityRequirement;
    private ScrollBarVisibility _verticalScrollBarVisibilityRequirement;
    private Thickness _marginRequirement = new Thickness(16);

    public DemoItem(string name, object content)
    {
        _name = name;
        Content = content;
    }

    public string Name
    {
        get { return _name; }
        set { this.MutateVerbose(ref _name, value, RaisePropertyChanged()); }
    }

    public object Content
    {
        get { return _content; }
        set { this.MutateVerbose(ref _content, value, RaisePropertyChanged()); }
    }

    public ScrollBarVisibility HorizontalScrollBarVisibilityRequirement
    {
        get { return _horizontalScrollBarVisibilityRequirement; }
        set { this.MutateVerbose(ref _horizontalScrollBarVisibilityRequirement, value, RaisePropertyChanged()); }
    }

    public ScrollBarVisibility VerticalScrollBarVisibilityRequirement
    {
        get { return _verticalScrollBarVisibilityRequirement; }
        set { this.MutateVerbose(ref _verticalScrollBarVisibilityRequirement, value, RaisePropertyChanged()); }
    }

    public Thickness MarginRequirement
    {
        get { return _marginRequirement; }
        set { this.MutateVerbose(ref _marginRequirement, value, RaisePropertyChanged()); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private Action<PropertyChangedEventArgs> RaisePropertyChanged()
    {
        return args => PropertyChanged?.Invoke(this, args);
    }
}

我的 MutateVerbose 函数如下所示:

public static void MutateVerbose<TField>(this INotifyPropertyChanged instance, ref TField field, TField newValue, Action<PropertyChangedEventArgs> raise, [CallerMemberName] string propertyName = null)
    {
        if (EqualityComparer<TField>.Default.Equals(field, newValue)) return;
        field = newValue;
        raise?.Invoke(new PropertyChangedEventArgs(propertyName));
    }

在这种情况下,我不知道如何通过单击按钮来切换选项卡。请帮帮我!

标签: c#wpfxamlmaterial-design

解决方案


推荐阅读