Use WPF styles like themes

Now I am creating an application using WPF. Now I want to change the appearance of the application depending on user input. This means that through the configuration window, users can decide how the application looks and depends on the choice, it must change the styles. How can I achieve this while using multiple styles for each configuration.

For instance -

The next rectangle consists of several texts. When you restart the application, it depends on the choice of the user, he must display the content (the changes are saved in some place, and he can easily get the current configuration data and depend on the saved details, which he must draw using WPF)

  • If the user selects an option to display only 4 text that he should display, as in the first image
  • If the user selects an option to display only 3 or 2 texts, it depends on the internal context, which will change the size of the rectangle (image 3/4).
  • For example, if this rectangle contains an image, it must resize the rectangle accordingly. If the user changes the settings for deleting the image from the rectangle, he must delete it and resize the rectangle accordingly (image 4)

enter image description here

+4
source share
3 answers

Place the texts ( TextBox ) and the image ( Image ) in the Grid to create the desired layout. Resizing will happen automatically.

Then bind the Visibility property of each of your texts and your image to the property of some object that saves the selected state in options. (The best solution is to store this information in some new class and assign an instance of this class to the DataContext your window.

For each of the bindings, create a value converter that returns Visibility.Visible or Visibility.Collapsed , based on whether the corresponding element should be visible or invisible with the current settings.


EDIT: Here is an example code:

Assuming your very simple settings object is as follows:

 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)); } } } } } 

This is where your GUI mode is stored. Pay attention to the implementation of INotifyPropertyChanged , so when binding to the Mode property, changes to the Mode property will automatically update everything related to it.

Then, for example, for text2, you can write the following value converter:

 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."); } } 

Since text2 is always displayed, except when only one text is GuiMode.OneText - GuiMode.OneText -, the corresponding Visibility values ​​are returned by the converter. Also note that this converter simply assumes that the input value is a GuiMode value. To do this correctly, you need to check what you get in value as well as targetType .

Once this is done, you can import the converter as a static resource into your Xaml:

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

Depending on which imported namespaces you may need to add the appropriate namespace prefix before Text2VisibilityConverter there.

The Visibility property of your text2 can be attached to the Mode property of the GuiSettings class using Text2VisibilityConverter , assuming that the GuiSettings instance in which you save your settings has been assigned the DataContext property in the window:

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

Once this works, you can add additional value conversion classes to make other controls visible.

+1
source

The question is pretty general, so I'll tell you about how to use styles and templates to control how your WPF controls look.

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

There are several ways to change the behavior of controls and actions at runtime.

The direct and understandable way (if you came from winforms) to interact with wpf templates is to override the OnApplyTemplate method and then install the template you want to use from the library of templates that you created or purchased,

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

But what is the best approach for you really depends on how you load the settings of your users and the fundamental design of your user interface, MVVM and MVC vs Custom Controls, etc.

+1
source

You can try something similar to this:

 <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> 

Code behind:

  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; } 
0
source

Source: https://habr.com/ru/post/1495356/


All Articles