c# – 使用主题等WPF样式

我现在正在使用
WPF创建一个应用程序.现在我想根据用户输入更改应用程序的外观.它的意思是,通过配置窗口,用户可以决定应用程序的外观,并根据选择它应该更改样式.我怎样才能实现这一点而不是每个配置使用多种样式.

例如-

以下矩形由几个文本组成.重新启动应用程序时,取决于用户选择它应该显示内容(更改保存在某些位置,并且可以轻松获取当前配置详细信息并依赖于保存的详细信息,它应使用WPF绘制外观)

> IF用户选择一些选项以显示它应显示的所有4个文本,如第一张图像
>如果用户选择某个选项以仅显示3或2个文本,则取决于内部上下文,它将重新调整矩形的大小(图像3/4).
>例如,如果此矩形包含图像,则应相应地重新调整矩形的大小.如果用户更改设置以从矩形中删除图片,则应将其删除并相应地重新调整矩形的大小(图4)

最佳答案 将文本(
TextBox)和图像(
Image)放在
Grid中以创建所需的布局.调整大小将自动进行.

然后,将每个文本和图像的Visibility property绑定到某个对象的属性,该对象存储在选项中选择的状态. (最佳解决方案是将此信息存储在您自己的一些新类中,并将该类的实例分配给窗口的DataContext property.

对于每个绑定,创建一个返回Visibility.VisibleVisibility.Collapsedvalue converter,具体取决于相应元素对于当前选项是可见还是不可见.

编辑:这是一些示例代码:

假设您非常简单的设置对象如下所示:

public enum GuiMode {
    FourTexts,
    ThreeTexts,
    OneText,
    ThreeTextsAndImage
}

public class GuiSettings : INotifyPropertyChanged
{
    public PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null) {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private GuiMode mode = GuiMode.FourTexts;

    public GuiMode Mode {
        get {
            return mode;
        }
        set {
            if (mode != value) {
                switch (value) {
                    case GuiMode.FourTexts:
                    case GuiMode.ThreeTexts:
                    case GuiMode.OneText:
                    case GuiMode.ThreeTextsAndImage:
                        mode = value;
                        OnPropertyChanged("Mode");
                        break;
                    default:
                        throw new InvalidEnumArgumentException("value", (int)value, typeof(GuiMode));
                }
            }
        }
    }
}

这将存储GUI的模式.注意INotifyPropertyChanged的实现,因此当绑定到Mode属性时,Mode属性的更改将自动更新绑定到它的任何内容.

然后,例如,对于text2,您可以编写以下值转换器:

public class Text2VisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        switch ((GuiMode)value) {
            case GuiMode.OneText:
                return Visibility.Collapsed;
            default:
                return Visibility.Visible;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException("This converter does not convert back.");
    }
}

由于text2始终可见,除了显示只有一个文本的状态 – GuiMode.OneText – 之外,转换器返回相应的Visibility值.另请注意,此转换器只是假设传入值是GuiMode值.要正确执行此操作,您应该检查您获得的值以及targetType.

完成此操作后,您可以将转换器作为静态资源导入Xaml:

<Window.Resources>
    <Text2VisibilityConverter x:Key="text2vis"/>
</Window.Resources>

根据您导入的命名空间,您可能需要在Text2VisibilityConverter前面的add the appropriate namespace prefix.

然后可以使用Text2VisibilityConverter将text2的Visibility property绑定到GuiSettings类的Mode属性,假设您存储设置的GuiSettings实例已分配给窗口的DataContext property

<TextBlock Text="Text 2" Visibility="{Binding Mode, Converter={StaticResource text2vis}}"/>

一旦有效,您可以为其他控件的可见性添加更多值转换器类.

点赞