Graeme_Grant
Обычно я бы попросил вас отправить код, прежде чем помогать, так как мы здесь не для того, чтобы писать ваш код для вас. Тем не менее, я сделаю исключение, чтобы вы начали.
Ключом к шаблону проектирования MVVM является привязка данных. Подробнее об этом вы можете прочитать здесь: Обзор Привязки Данных | Microsoft Docs[^]
Вторая часть вашего вопроса касается триггеров XAML ... Делайте это, когда это произойдет. Это называется триггером события. Вы можете узнать больше о триггерах здесь: Стилизация и использование шаблонов | Майкрософт документы[^]
Кроме того, хорошим учебным ресурсом для WPF является: Добро пожаловать - полный учебник WPF[^] и для MVVM есть много ресурсов, чтобы учиться у них: учебник wpf mvvm - поиск в Google[^]
Вот рабочий пример, основанный на вашем вопросе...
Для привязки данных приведем несколько базовых классов для привязки данных:
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;
}
Затем ViewModel:
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
}
И, наконец, вид:
<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>
Когда вы наводите курсор мыши на текстовое поле, фон текстового поля меняет цвет, а когда вы вводите числовое значение в любом из первых 2 текстовых полей, значения в последних 2 будут автоматически вычисляться. Ключ-это привязка данных. Не торопитесь и узнайте, как это работает, по ссылкам, приведенным выше.