【问题标题】:Change content stack panel dynamically with button click WPF使用按钮单击 WPF 动态更改内容堆栈面板
【发布时间】:2020-02-28 05:35:18
【问题描述】:

我想在同一窗口中单击按钮时更改堆栈面板内容/数据。

我在窗口的左侧和右侧有一个菜单列表,我有 2 个要更新的堆栈面板。这实际上是我的配置屏幕。以下是我的 XAML 代码:

<Window x:Class="Manager.Screens.Configurations"
        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:Manager.Screens"
        mc:Ignorable="d"
        Title="Configurations" Height="850" Width="1000" WindowStyle="None" >

    <Border 
          BorderBrush="Black" 
          BorderThickness="0" 
          Padding="0">
        <Grid Background="White" ShowGridLines="True" Margin="-3,0,0,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="200*"/>
                <ColumnDefinition Width="263*"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>

            <StackPanel Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Name="StackPanel1" VerticalAlignment="Top" Height="Auto" Width="Auto">
                <Image Source="Resources\Images\config_back.jpg" Stretch="Fill" Opacity="0.65" Height="Auto" Margin="-3,-2,0,0"/>
                <Button Margin="0,-1450,0,60" Height="38" Background="Transparent">
                    <StackPanel Orientation="Horizontal" Width="332">
                        <Image Source="Resources\Images\tools.png" Margin="75,0,25,0"/>
                        <TextBlock Text="General" VerticalAlignment="Center" FontSize="18" FontWeight="Bold" Foreground="#FFFF8C3D"/>
                    </StackPanel>
                </Button>
                <Button Margin="0,-1350,0,10" Height="38" Background="Transparent">
                    <StackPanel Orientation="Horizontal" Width="332">
                        <Image Source="Resources\Images\setting.png" Margin="75,0,25,0"/>
                        <TextBlock Text="Settings" VerticalAlignment="Center" FontSize="18" FontWeight="Bold" Foreground="#FFFF8C3D"/>
                    </StackPanel>
                </Button>
                <Button Margin="0,-1250,0,-40" Height="38" Background="Transparent">
                    <StackPanel Orientation="Horizontal" Width="332">
                        <Image Source="Resources\Images\user.png" Margin="75,0,25,0"/>
                        <TextBlock Text="Limits/Stations" VerticalAlignment="Center" FontSize="18" FontWeight="Bold" Foreground="#FFFF8C3D"/>
                    </StackPanel>
                </Button>
                <Button Margin="0,-1150,0,-90" Height="38" Background="Transparent">
                    <StackPanel Orientation="Horizontal" Width="332">
                        <Image Source="Resources\Images\user.png" Margin="75,0,25,0"/>
                        <TextBlock Text="Portions" VerticalAlignment="Center" FontSize="18" FontWeight="Bold" Foreground="#FFFF8C3D"/>
                    </StackPanel>
                </Button>
                <Button Margin="0,-1050,0,-140" Height="38" Background="Transparent">
                    <StackPanel Orientation="Horizontal" Width="332">
                        <Image Source="Resources\Images\user.png" Margin="75,0,25,0"/>
                        <TextBlock Text="Label Templates" VerticalAlignment="Center" FontSize="18" FontWeight="Bold" Foreground="#FFFF8C3D"/>
                    </StackPanel>
                </Button>

                <Button Margin="0,-950,0,-190" Height="38" Background="Transparent">
                    <StackPanel Orientation="Horizontal" Width="332">
                        <Image Source="Resources\Images\user.png" Margin="75,0,25,0"/>
                        <TextBlock Text="RFID Containers" VerticalAlignment="Center" FontSize="18" FontWeight="Bold" Foreground="#FFFF8C3D"/>
                    </StackPanel>
                </Button>
                <Button Margin="0,-850,0,-240" Height="38" Background="Transparent">
                    <StackPanel Orientation="Horizontal" Width="332">
                        <Image Source="Resources\Images\user.png" Margin="75,0,25,0"/>
                        <TextBlock Text="User Management" VerticalAlignment="Center" FontSize="18" FontWeight="Bold" Foreground="#FFFF8C3D"/>
                    </StackPanel>
                </Button>
            </StackPanel>

            <StackPanel Grid.Column="1" Grid.Row="0" HorizontalAlignment="Stretch" Name="StackPanel2" VerticalAlignment="Top" Orientation="Vertical">

            </StackPanel>

            <StackPanel Grid.Column="2" Grid.Row="0" HorizontalAlignment="Left" Name="StackPanel3" VerticalAlignment="Top">
                <TextBlock FontSize="18" HorizontalAlignment="Center" Margin="0,0,0,15">StackPanel3</TextBlock>
                <Button Margin="10">Button 7</Button>
                <Button Margin="10">Button 8</Button>
                <Button Margin="10">Button 9</Button>
                <TextBlock>ColumnDefinition.Width="Auto"</TextBlock>
                <TextBlock>StackPanel.HorizontalAlignment="Left"</TextBlock>
                <TextBlock>StackPanel.VerticalAlignment="Top"</TextBlock>
                <TextBlock>StackPanel.Orientation="Vertical"</TextBlock>
                <TextBlock>Button.Margin="10"</TextBlock>
            </StackPanel>
        </Grid>
    </Border>

</Window>

到目前为止,我还没有编写任何控件或函数,请帮助我,因为我是新手,如何在 WPF 中完成。

【问题讨论】:

  • 要么使用ToggleButton 而不是Button,并将它的IsCheckedproperty 绑定到您要显示/隐藏的控件的Visibility。或者如果您希望它是Button,则使用Button,但在您的ViewModel/代码后面创建一个布尔属性以指示可见性,将其绑定到您要显示/隐藏和切换的控件的Visibility每当您按下Button 时,它都会显示。在任何情况下 - 不要忘记使用BooleanToVisibilityConverter
  • 你能写代码并展示如何实现吗?
  • 在点击事件中写下你想要的:StackPanel .Children.Add(YourControlName);或 StackPanel .Children.Remove(YourControlName);

标签: c# wpf wpf-controls


【解决方案1】:

基本上有三种主要方法可以在视图上显示/隐藏控件。下面是为您提供每个示例的代码:

XAML:

<Window 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"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Rectangle Grid.Column="0" Grid.Row="0" Visibility="{Binding IsBlueRectangleVisible, Converter={StaticResource BooleanToVisibilityConverter}}" Fill="Blue" />
        <Button Grid.Column="1" Grid.Row="0" Content="Binding to ViewModel" Command="{Binding BlueRectangleSwitchCommand}"/>

        <Rectangle Grid.Column="0" Grid.Row="1" Visibility="{Binding ElementName=toggleBtn, Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}" Fill="Red" />
        <ToggleButton Grid.Column="1" Grid.Row="1" x:Name="toggleBtn" Content="Toggle switch" />

        <Rectangle x:Name="greenRectangle" Grid.Column="0" Grid.Row="2" Fill="Green" />
        <Button Grid.Column="1" Grid.Row="2" Content="Code behind" Click="GreenRectangleBtnClick"/>
    </Grid>
</Window>

后面的代码:

public partial class MainWindow : Window, INotifyPropertyChanged
{

    public MainWindow()
    {
        InitializeComponent();

        // Blue rectangle
        // Initialize the command that is binded to one of your buttons
        BlueRectangleSwitchCommand = new RelayCommand(o => 
        {
            // Switches the flag binded to Visibility property of one of your Rectangles
            IsBlueRectangleVisible = !IsBlueRectangleVisible;
            // Notify that UI shoud be re-rendered
            OnPropertyChanged(nameof(IsBlueRectangleVisible));
        });
        // Next line is needed in order to bind this object to the DataContext of itself (wierd, isn't it?)
        // So the MainWindow would know where to llok up for the properties you are binding to in XAML
        DataContext = this;
    }

    // Blue rectangle
    // Property that is binded to Visibility property of one of your Rectangles
    public bool IsBlueRectangleVisible { get; set; }
    // Blue rectangle
    // Property that is binded to Command property of one of your Rectangles
    public ICommand BlueRectangleSwitchCommand { get; private set; }

    // Blue rectangle
    // This implementation of INotifyPropertyChanged interface allows you to use OnPropertyChanged 
    // that is needed for notifying UI that your properties changed
    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    #endregion

    // Green rectangle
    private void GreenRectangleBtnClick(object sender, RoutedEventArgs e)
    {
        greenRectangle.Visibility = greenRectangle.Visibility == Visibility.Visible
            ? Visibility.Collapsed
            : Visibility.Visible;
    }
}

我添加了评论,以便您可以轻松区分它们。由您决定哪一个更适合您。

但这是我的建议:

  1. 如果您不需要跟踪实际状态,请使用切换开关(红色);
  2. 如果您需要跟踪开关的状态或从后面的代码进行开关 - 使用绑定到 ViewModel(蓝色);
  3. 切勿使用第三个。好吧,这是一个笑话,有点。如果您需要在一个小型应用程序中使用非常简单的用户界面 - 随心所欲地使用它。但是,如果您的应用程序有可能会增长,那么您需要分离关注点、测试能力等,甚至不要考虑这种方法。它将使您的应用程序成为面条盘(绿色)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-11
    • 1970-01-01
    相关资源
    最近更新 更多