【问题标题】:Use WPF styles like themes使用 WPF 样式,如主题
【发布时间】:2013-08-05 16:23:00
【问题描述】:

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

例如-

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

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

【问题讨论】:

  • Window.SizeToContent 设置为WidthAndHeight? :msdn.microsoft.com/en-us/library/…
  • 似乎您需要来自DynamicResources 并根据您选择的内容以编程方式更改其值。首先:您熟悉面板的Template 选项吗?如果是这样,您可以使用不同的模板在 ResourceDictionary 中创建 4 个不同的 Styles(每个模板都适合您的设计),并以编程方式更改它们。
  • @Bolu 这并不完全符合他的需求。他还需要改变内容,而不仅仅是定位。这就是样式(在这种情况下管理 Template 内容)。
  • @Sonhja,但他也需要 Window 来调整内容的大小?

标签: c# wpf visual-studio-2010


【解决方案1】:

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

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

对于每个绑定,创建一个 value converter,它会根据相应元素在当前选项下是否可见或不可见而返回 Visibility.VisibleVisibility.Collapsed


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

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

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 值。另请注意,此转换器仅假定传入的valueGuiMode 值。要正确执行此操作,您应该检查valuetargetType 中的内容。

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

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

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

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

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

一旦成功,您就可以为其他控件的可见性添加更多值转换器类。

【讨论】:

  • 这是一种非常简单易行的方法! :) 这样,就不需要样式了。仅开关盒。
  • 太棒了。请给我一些示例代码(仅限,如何使用值转换器)
  • @yapa:我添加了一个示例和一些解释;如果缺少任何提示,请告诉我。
  • 我会检查的。非常感谢
【解决方案2】:

这个问题很笼统,所以我将向您介绍如何使用样式和模板来控制 WPF 控件的外观。

http://msdn.microsoft.com/en-us/magazine/cc163497.aspx

您可以通过多种方式更改控件在运行时的外观和行为。

与 wpf 模板交互的一种直接且易于理解的方式(如果您来自 winforms)是通过覆盖 OnApplyTemplate 方法,然后从您创建或采购的模板库中设置您要使用的模板.

http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.onapplytemplate.aspx

但对您来说最好的方法实际上取决于您如何加载用户偏好以及 UI 的基本设计、MVVM、MVC 和自定义控件等。

【讨论】:

    【解决方案3】:

    您可以尝试类似的方法:

    <Grid>
        <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" Height="30">
            <Button Content="Option1" Name="Option1" Click="Option1_OnClick"></Button>
            <Button Content="Option2" Name="Option2" Click="Option2_OnClick"></Button>
            <Button Content="Option3" Name="Option3" Click="Option3_OnClick"></Button>
            <Button Content="Full" Name="Full" Click="Full_OnClick"></Button>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
        <Image Source="/WpfApplication3;component/Resources/vaca.png" HorizontalAlignment="Left" VerticalAlignment="Top" Width="150" Height="150" Name="Image"></Image>
            <StackPanel Orientation="Vertical" >
                <Label Content="Text1" Name="Text1" />
                <Label Content="Text2" Name="Text2" />
                <Label Content="Text3" Name="Text3" />
                <Label Content="Text4" Name="Text4" />
            </StackPanel>
        </StackPanel>
    </Grid>
    

    后面的代码:

     private void Option1_OnClick(object sender, RoutedEventArgs e)
        {
            Image.Visibility = Visibility.Collapsed;
        }
    
        private void Option2_OnClick(object sender, RoutedEventArgs e)
        {
            Image.Visibility = Visibility.Collapsed;
            Text4.Visibility = Visibility.Collapsed;
        }
    
        private void Option3_OnClick(object sender, RoutedEventArgs e)
        {
            Image.Visibility = Visibility.Collapsed;
            Text4.Visibility = Visibility.Collapsed;
            Text3.Visibility = Visibility.Collapsed;
            Text2.Visibility = Visibility.Collapsed;
        }
    
        private void Full_OnClick(object sender, RoutedEventArgs e)
        {
            Image.Visibility = Visibility.Visible;
            Text4.Visibility = Visibility.Visible;
            Text3.Visibility = Visibility.Visible;
            Text2.Visibility = Visibility.Visible;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-16
      • 2021-03-01
      • 2014-12-02
      相关资源
      最近更新 更多