Style recommended by WPF excellent components

Posted by shezz on Mon, 07 Mar 2022 08:20:55 +0100

1, Introduction

Stylet is an MVVM component based on WPF. Although WPF itself has its own MVVM function, it is not very convenient to implement. Through stylet, users can enjoy the comfortable experience brought by MVVM with little code.

Currently, Stylet supports: Net Framerwork 4.5,. Net Core 3.0,. Net 5 or above.  

 

2, Build basic framework

1. After creating a new project, add the following components through Nuget:

  

2. New window mainshelview, new class mainshelviewmodel

public class MainShellViewModel : Stylet.Screen
{
}

Style has naming requirements for views and models, which must appear in pairs in the form of XXXView and XXXViewModel.

 

3. Create a new class Bootstrapper

    public class Bootstrapper : Bootstrapper<MainShellViewModel>
    {
        protected override void ConfigureIoC(IStyletIoCBuilder builder)
        {
            // Configure the IoC container in here
        }

        protected override void Configure()
        {
            // Perform any other configuration before the application starts
        }
    }

 

4. Edit app Xmal, delete StartupUri="MainWindow.xaml", as follows:

<Application x:Class="NiceComponents.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:NiceComponents"
             xmlns:s="https://github.com/canton7/Stylet">
    <Application.Resources>
        <s:ApplicationLoader>
            <s:ApplicationLoader.Bootstrapper>
                <local:Bootstrapper />
            </s:ApplicationLoader.Bootstrapper>
        </s:ApplicationLoader>
    </Application.Resources>
</Application>

Then compile and run.

MainWindow. In the root directory of the project Xaml is useless and can be deleted.

 

3, Basic usage

1. Bind

XMAL: 
<ProgressBar Value="{Binding ProgressValue}" Visibility="{Binding ProgressVisibility}" Maximum="100" />
<Slider Value="{Binding ProgressValue}" Maximum="100" />
<CheckBox Content="Show" IsChecked="{Binding IsProgressShow}"/>

CODE: 
public class MainShellViewModel : Stylet.Screen
{
    public int ProgressValue { get; set; }
    public bool IsProgressShow { get; set; } = true;
    public Visibility ProgressVisibility => IsProgressShow ? Visibility.Visible : Visibility.Collapsed;
}

The above code realizes the linkage of a ProgressBar control and a Slider control, and controls whether the progressbar is displayed through a CheckBox control. The code is very concise and fully reflects the elegance of MVVM.

 

2. Command

XMAL: 
  <TextBox Text="{Binding InputString, UpdateSourceTrigger=PropertyChanged}"/>
  <TextBlock  Text="{Binding OutputString}"/>
  <Button Content="Show" Command="{s:Action ShowString}" />

CODE: 
public class MainShellViewModel : Stylet.Screen
 { 
        public string InputString { get; set; }
        public string OutputString { get; set; }
        public void ShowString()
        {
            OutputString = $"Your string is : {InputString}";
        }
        public bool CanShowString => !string.IsNullOrEmpty(InputString);
}

Call the background method through Command="{s:Action ShowString}". Add a Can before the method name to represent the defense attribute. The IsEnabled state of the button Can be controlled through the CanShowString attribute.

Some controls have no Command property and are called in the same way:

<TextBox TextChanged="{s:Action TextChanged}" IsEnabled={Binding IsTextBoxEnabled} />

public void TextChanged()
{
      Debug.WriteLine("TextChanged");
}

At this time, the defense property cannot be used. If necessary, you can define a common bool type variable Binding to the IsEnabled property of the control.

 

3. Binding list

XMAL: 
  <ListBox ItemsSource="{Binding StringList}" SelectedItem="{Binding SelectedString}" />
  <Button Content="Add String" Command="{s:Action AddString}" />
  <Button Content="Delete String" Command="{s:Action DeleteString}" />
    
CODE: 
    public class MainShellViewModel : Stylet.Screen
    {
public List<string> StringList { get; set; } = new List<string>(); public string SelectedString { get; set; } public void AddString() { StringList.Add($"Item{StringList.Count + 1}"); } public void DeleteString() { StringList.Remove(SelectedString); } public bool CanDeleteString => SelectedString != null; }

In WPF, many controls are bound to list, such as ListBox, ComboBox, DataGrid, etc. The above code realizes the addition and deletion of a list.

Run the above code and you will find that the program cannot run correctly. Through Debug, you will find that the AddString method has been executed and the number of StringList lists has increased, but the ListBox on the interface has not changed. For MVVM framework, this is a very common problem and a very easy mistake.

When we change an object, the Fody framework will automatically call the PropertyChanged method, and the foreground will update the interface only after receiving the PropertyChanged event. For List, calling its Add method only changes the properties of the object, not the object itself, so there is no PropertyChanged event.

To solve this problem, you can use BindingList instead of List. This class will also send PropertyChanged event when the content changes. In addition, the style framework specifically provides a BindableCollection class to load the List that needs dynamic binding. This class should be used first.

Download address of the above code: NiceComponents · Bruce/Learn WPF - codecloud - Open Source China (gitee.com)

In the next section, we will introduce some more complex applications of the style framework.

Topics: WPF