如何添加到DataTrigger属性“可见性”折叠/可见?

时间:2019-08-08 16:07:47

标签: c# wpf xaml

我想创建一个漂亮的页面,当我选择角色时可以更改表单。

当我选择用户角色时,我隐藏了开发人员字段,并且希望像图片一样调整表单的大小

enter image description here

如果我选择开发人员,则表单应具有傻瓜表单,如图片所示

enter image description here

如果将来我要在该领域添加新角色,这对我来说是个好方法

但是我不知道如何调整大小?

我刚刚编写了如何隐藏或显示公司字段的代码。我花了很多时间来查找有关如何执行此操作的信息,但未成功。

 <Page.Resources>

    <Storyboard x:Key="OpenMenu">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" >
            <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="250"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>

    <Storyboard x:Key="CloseMenu">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" >
            <EasingDoubleKeyFrame KeyTime="0" Value="250"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>

    <Style TargetType="{x:Type TextBox}" x:Key="companyStyle" BasedOn="{StaticResource MaterialDesignFloatingHintTextBox}" >
        <Style.Triggers>

            <DataTrigger Binding="{Binding Path=SelectedValue, ElementName=comboBoxRole}" Value="AppDeveloper">
                <DataTrigger.EnterActions>
                    <BeginStoryboard Name="sb" Storyboard="{StaticResource OpenMenu}"/>
                </DataTrigger.EnterActions>
                <DataTrigger.ExitActions>
                    <RemoveStoryboard BeginStoryboardName="sb" />
                </DataTrigger.ExitActions>
            </DataTrigger>

            <DataTrigger Binding="{Binding Path=SelectedValue, ElementName=comboBoxRole}" Value="EndUser">
                <DataTrigger.EnterActions>
                    <BeginStoryboard Name="sb2" Storyboard="{StaticResource CloseMenu}"/>
                </DataTrigger.EnterActions>
                <DataTrigger.ExitActions>
                    <RemoveStoryboard BeginStoryboardName="sb2" />
                </DataTrigger.ExitActions>
            </DataTrigger>

        </Style.Triggers>
    </Style>

</Page.Resources>

,并且需要使用动画来使此调整大小平滑,也许有人知道如何实现或阅读有关内容。

1 个答案:

答案 0 :(得分:1)

您需要对此保持机智,因为我们必须处理两件事;

  1. 调整窗口大小时,需要两个部分相应地展开/折叠。
  2. 允许动画。

因此,让我们进入第一个窗口,如何设计窗口。表单的左手边(LHS)对两者都是通用的,必须始终显示。仅当所选用户是开发人员时,右侧(RHS)才可见。这意味着,您需要LHS填充表格的宽度,而RHS仅在可见时占用所需空间。这是利用Width=Auto的好机会。我将有一个2 x 2网格,第一行跨越两列,并在其中拥有ComboBox,然后在第二行的每一列中使用两组TextBox控件。我正在使用Border控件来表示这两个控件。因此,我将在不设置ColumnDefinition属性的情况下使用第一个Width,而在第二个属性中使用Width=Auto

<Grid Margin="10">
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <ComboBox Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2"
              Width="100" Height="24" Margin="4"
              HorizontalAlignment="Center" VerticalAlignment="Center"/>

    <Border Grid.Column="0" Grid.Row="1"
            Margin="10"
            Background="LightSkyBlue" CornerRadius="4"/>

    <Border Grid.Column="1" Grid.Row="1" 
            Margin="10" Width="150"
            Background="LightGreen" CornerRadius="4"/>
</Grid>

请注意,LHS边框未指定宽度,因为它将占用整个可用宽度,在这种情况下,RHS的宽度将设置为150。它应该看起来像这样:

enter image description here

现在,我正在尝试在这里完成两件事。

  1. 使用时选择AppDeveloper,将同时显示RHS和LHS。选择EndUser时,RHS边框(绿色的边框)Visibility=Collapsed变得不可见并且不占用任何空间。

    • 为此,我将使用BooleanToVisibilityConverter,并将RHS边框的Visibility属性绑定到名为bool的代码中的ExtraDetails变量。
  2. 同时,选择EndUser时,Window的宽度会缩短,并且会在动画中发生。同样,当选择AppDeveloper时,窗口宽度再次扩展为全尺寸,并带有动画。

    • 在这里,我将使用Storyboard类,并设置一个动画,该动画可根据时间更改窗口的Width

此外,我将使用两个public成员变量,一个用于填充组合框的列表和一个用于表示组合中所选项的选定项。请注意,主窗口的Name属性对于动画很重要。

因此,当所有内容放在一起时,您的XAML看起来像这样:

<Window ...
        Name="mainWin"
        Title="MainWindow" Height="300" Width="400">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVis" />
        <Storyboard x:Key="showWin">
            <DoubleAnimation Storyboard.TargetName="mainWin" Storyboard.TargetProperty="Width" Duration="0:0:.5" To="400" BeginTime="0:0:0"/>
        </Storyboard>

        <Storyboard x:Key="hideWin">
            <DoubleAnimation Storyboard.TargetName="mainWin" Storyboard.TargetProperty="Width" Duration="0:0:.5" To="200" BeginTime="0:0:0"/>
        </Storyboard>
    </Window.Resources>
    <Grid Margin="10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <ComboBox Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2"
                  Width="100" Height="24" Margin="4"
                  HorizontalAlignment="Center" VerticalAlignment="Center"
                  ItemsSource="{Binding ComboItems}"
                  SelectedValue="{Binding SelectedItem}"
                  SelectionChanged="ComboBox_SelectionChanged"/>

        <Border Grid.Column="0" Grid.Row="1"
                Margin="10"
                Background="LightSkyBlue" CornerRadius="4"/>

        <Border Grid.Column="1" Grid.Row="1" 
                Margin="10" Width="150"
                Background="LightGreen" CornerRadius="4"
                Visibility="{Binding Path=ExtraDetails, Converter={StaticResource BoolToVis}}"/>
    </Grid>
</Window>

以及背后的代码:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private List<string> _comboItems;

    public List<string> ComboItems
    {
        get { return _comboItems; }
        set
        {
            if (value != _comboItems)
            {
                _comboItems = value;
                OnPropertyChanged("ComboItems");
            }
        }
    }

    private string _selectedItem;

    public string SelectedItem
    {
        get { return _selectedItem; }
        set
        {
            if (value != _selectedItem)
            {
                _selectedItem = value;
                OnPropertyChanged("SelectedItem");
            }
        }
    }

    private bool _extraDetails;

    public bool ExtraDetails
    {
        get { return _extraDetails; }
        set
        {
            if (value != _extraDetails)
            {
                _extraDetails = value;
                OnPropertyChanged("ExtraDetails");
            }
        }
    }

    public Storyboard showWin;
    public Storyboard hideWin;

    public MainWindow()
    {
        InitializeComponent();
        PopulateCombo();
        showWin = (Storyboard)Resources["showWin"];
        hideWin = (Storyboard)Resources["hideWin"];
        DataContext = this;
    }

    private void PopulateCombo()
    {
        ComboItems = new List<string>
        {
            "EndUser",
            "AppDeveloper"
        };
        SelectedItem = ComboItems.Last();
    }

    private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (SelectedItem == "AppDeveloper")
        {
            ExtraDetails = true;
            BeginStoryboard(showWin);
        }
        else
        {
            ExtraDetails = false;
            BeginStoryboard(hideWin);
        }
    }
}

请注意,在构造函数中,我“获取”了Storyboard中定义的两个XAML资源。然后,在ComboBox_SelectionChanged事件处理程序中,我使用适当的Storyboard来调整带有动画的窗口的大小。通过同时设置ExtraDetails,您还可以显示/隐藏RHS绿色部分。