Click here to Skip to main content
15,888,401 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
I am newbie in WPF world and want to create a solution where I want to write MVVM program using C# and XAML to perform some simple computations.

The MainWindow xaml has an named outer grid View.

The xaml code behind (MainWindow.xaml.cs) may only contain a constructor

which sets the View.DataContext to an instance of a new ViewModel class.

 public partial class MainWindow : Window

    {

        public MainWindow()

        {

            InitializeComponent();

            View.DataContext = new ViewModel();

        }

    }
Use xaml and additional code / classes to implement the bindings to implement

the following behavior.

MainWindow user interface contains :

two input textboxes A and B (with Width=100 and Height=25).

two result textboxes containing : C = A + B, and D = A * B, these update, when A or B change.

MainWindow background color is:

LightBlue when mouse cursor enters A inputbox

LightGreen when mouse cursor enters B inputbox

LightGray all other cases.


What I have tried:

I am looking for an ideas to start this.
Posted
Updated 3-Sep-18 3:07am

Normally I would ask you to post code before helping as we are not here to write your code for you. However, I will make an exception to get you started.

The key to the MVVM Design Pattern is Data Binding. You can read more about it in detail here: Data Binding Overview | Microsoft Docs[^]

The second part of your question is about XAML Triggers ... Do this when this happens. This is called an Event Trigger. You can learn more about Triggers here: Styling and Templating | Microsoft Docs[^]

Also, a good learning resource for WPF is: Welcome - The complete WPF tutorial[^] and for MVVM there are many resources to learn from: wpf mvvm tutorial - Google Search[^]

Here is a working example based on your question...

For data binding, here are a couple of base classes for Data Binding:
C#
public abstract class ObservableBase : INotifyPropertyChanged
{
    public void Set<TValue>(ref TValue field, TValue newValue, [CallerMemberName] string propertyName = "")
    {
        if (!EqualityComparer<TValue>.Default.Equals(field, default(TValue)) && field.Equals(newValue)) return;
        field = newValue;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}


public abstract class ViewModelBase : ObservableBase
{
    public bool IsInDesignMode
        => (bool) DesignerProperties.IsInDesignModeProperty
            .GetMetadata(typeof(DependencyObject))
            .DefaultValue;
}

Next the ViewModel:
C#
public class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {
        if (IsInDesignMode)
        {
            // design time only...
            valueA = 5;
            valueB = 6;
            Calc();
        }
        else
        {
            // runtime only...
        }
    }

    #region Properties

    private int valueA;
    public int ValueA
    {
        get => valueA;
        set
        {
            Set(ref valueA, value);
            Calc();
        }
    }

    private int valueB;
    public int ValueB
    {
        get => valueB;
        set
        {
            Set(ref valueB, value);
            Calc();
        }
    }

    private int valueC;
    public int ValueC
    {
        get => valueC;
        set => Set(ref valueC, value);
    }

    private int valueD;
    public int ValueD
    {
        get => valueD;
        set => Set(ref valueD, value);
    }

    #endregion

    #region Methods

    private void Calc()
    {
        ValueC = valueA + valueB;
        ValueD= valueA * valueB;
    }

    #endregion
}

And lastly, the View:
XML
<Window x:Class="WpfMvvmSimple.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:l="clr-namespace:WpfMvvmSimple"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.DataContext>
        <l:MainViewModel/>
    </Window.DataContext>

    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.Resources>
            <Style TargetType="TextBlock">
                <Setter Property="VerticalAlignment" Value="Center"/>
            </Style>
            <Style TargetType="TextBox" x:Key="TextBox">
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="Margin" Value="10"/>
                <Setter Property="Width" Value="100"/>
                <Setter Property="Height" Value="25"/>
                <Setter Property="Grid.Column" Value="1"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="Silver" />
                    </Trigger>
                </Style.Triggers>
            </Style>
            <Style TargetType="TextBox" x:Key="TextBoxA" BasedOn="{StaticResource TextBox}">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="LightBlue" />
                    </Trigger>
                </Style.Triggers>
            </Style>
            <Style TargetType="TextBox" x:Key="TextBoxB" BasedOn="{StaticResource TextBox}">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="LightGreen" />
                    </Trigger>
                </Style.Triggers>
            </Style>
            <Style TargetType="TextBox" BasedOn="{StaticResource TextBox}"/>
        </Grid.Resources>

        <TextBlock Text="Value A"/>
        <TextBox Text="{Binding ValueA, UpdateSourceTrigger=PropertyChanged}"
                 Style="{StaticResource TextBoxA}"/>

        <TextBlock Text="Value B" Grid.Row="1"/>
        <TextBox Text="{Binding ValueB, UpdateSourceTrigger=PropertyChanged}"
                 Style="{StaticResource TextBoxB}"
                 Grid.Row="1"/>

        <TextBlock Text="Value C" Grid.Row="2"/>
        <TextBox Text="{Binding ValueC}"
                 IsReadOnly="True"
                 Grid.Row="2"/>

        <TextBlock Text="Value D" Grid.Row="3"/>
        <TextBox Text="{Binding ValueD}"
                 IsReadOnly="True"
                 Grid.Row="3"/>


    </Grid>
</Window>

When your mouse hovers over a textbox, the textbox background will change color, and when you enter a numeric value in either of the first 2 textboxes, the values in the last 2 will auto calculate. The key is Data Binding. Take your time and learn how this works from the links provided above.
 
Share this answer
 
v2
Comments
Rajeshyadav12 3-Sep-18 20:03pm    
Thank you so much. I will have a look on the link you provided.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900