4

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

例如-

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

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

在此处输入图像描述

4

3 回答 3

1

这个问题很笼统,所以我将向您介绍如何使用样式和模板来控制 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 和自定义控件等。

于 2013-08-05T16:36:07.013 回答
1

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

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

对于每个绑定,创建一个值转换器,该转换器返回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值由转换器返回。另请注意,此转换器仅假定传入value的是一个GuiMode值。要正确执行此操作,您应该检查您所获得的内容value以及targetType.

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

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

根据您导入的命名空间,您可能需要在前面添加适当的命名空间前缀Text2VisibilityConverter

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

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

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

于 2013-08-05T16:30:52.987 回答
0

您可以尝试类似的方法:

<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;
    }
于 2013-08-06T08:12:02.900 回答