【问题标题】:Xaml: design a layout with dynamically visible componentsXaml:设计具有动态可见组件的布局
【发布时间】:2021-09-05 02:11:48
【问题描述】:

在 mvvm 应用程序中,窗口内的某些区域(实际上它是 MainWindow 内的 UserControl)根据用户选择动态显示。

变化的块在 Stackpanels 内,我有 4 个,一次只显示一个。这是通过将 Visibility 绑定到 bool 属性并使用 BooleanToVisibilityConverter 完成的。

我将所有备用 StackPanel 放在父控件中。它工作正常,但在 Visual Studio 中的设计阶段,我看到了所有这些,所以我在确定最终布局时遇到了问题。

如何轻松创建具有多个控件的布局,这些控件共享相同的窗口区域并一次显示一个?

【问题讨论】:

    标签: wpf xaml visual-studio-designer


    【解决方案1】:

    ,但是在 Visual Studio 的设计阶段,我看到了所有这些,所以我在确定最终布局时遇到了问题。

    通过在 Visual Studio 中调出Document Outline 选项卡可以轻松解决此问题。打开后,导航到可见树并切换 眼球 以可见地隐藏/取消隐藏不感兴趣的控件; 仅在设计期间

    【讨论】:

    • 我试过了,但这不是我想要的。切换到隐藏会将 d:IsHidden="True" 添加到控件中,该控件不可见,但不会在窗口中释放其区域。我需要将其折叠起来,以便下方的控件可以抬起并填充其区域。
    • 然后您需要临时更改硬编码顶部对象的可见性,以允许发生fill 操作。这是设计模式下的唯一选择。
    • 另一个答案可能是您正在寻找的解决方案,以在设计模式下操作 VM 以打开/关闭/隐藏控件。
    【解决方案2】:

    设置仅设计时数据上下文

    通过设置设计时数据上下文可以大大简化在 Studio Designer 中开发 XAML。

    一种实现基于设置重复的DataContext,在最终编译期间将被忽略。

    要实现切换,请添加到 ViewModel,该属性将通知设计人员是否可以在开发模式下使用。


    我在这个例子中使用了 MVVMLight 情况,但是对于这个声明的实例属性 IsInDesignMode 和静态属性 ViewModelBase.IsInDesignModeStatic

    例子:

    using System.ComponentModel;
    
    namespace DataContextDesignTime.Example
    {
        public class MyViewModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            private bool _flag;
            public bool Flag
            {
                get => _flag;
                set
                {
                    if (!Equals(_flag, value))
                    {
                        _flag = value;
                        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Flag)));
                        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(NotFlag)));
                    }
                }
            }
    
            public bool NotFlag => !Flag;
        }
    }
    
    <Window x:Class="DataContextDesignTime.Example.ExamleWindow"
            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:DataContextDesignTime.Example"
            mc:Ignorable="d"
            Title="ExamleWindow" Height="450" Width="800">
        <d:Window.DataContext>
            <local:MyViewModel Flag="True" NotFlag="True"/>
        </d:Window.DataContext>
        <Window.Resources>
            <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
        </Window.Resources>
        <StackPanel>
            <Border Background="LightBlue" Height="200"
                    Visibility="{Binding Flag, Converter={StaticResource BooleanToVisibilityConverter}}"/>
            <Border Background="LightGreen" Height="400"
                    Visibility="{Binding NotFlag, Converter={StaticResource BooleanToVisibilityConverter}}"/>
        </StackPanel>
    </Window>
    

    在此示例中,您可以在 XAML 或属性浏览器中更改属性值。
    您将立即看到绑定、触发器的工作情况,以及某些数据的显示如何变化。



    注意

    这在更复杂的虚拟机/包上可能会失败,但通常在设计时设置 DataContext 并不困难。

    我需要重新编译项目才能看到属性的变化。

    XAML 设计器面板有一个«启用/禁用项目代码»按钮。

    【讨论】:

    • 我今天学到了一些东西,这是一个非常有效的替代解决方案。
    • 我需要重新编译项目才能看到属性的变化。这是预期的行为吗?我在没有 MVVMLight 的情况下进行了测试
    • 不应该是这样的。即使是 INotyfyPropertyChanged 实现也不需要从 XAML 更改。这在 VS2017 和 2019 中一直对我有用。我没有在其他人中尝试过。
    • 我更新了 Studio 并与 XAML 同步也停止了对我的工作!似乎某些设置已更改。现在我正在寻找可能是什么问题。
    • 我找到了原因。阅读我的答案的补充。
    猜你喜欢
    • 1970-01-01
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    • 2019-10-07
    • 2014-08-29
    • 2015-01-21
    • 2015-04-05
    • 1970-01-01
    相关资源
    最近更新 更多