Basic desktop application event interaction
Event Driven vs. Data Driven
Window Data Model Encapsulation
//MainWindow.XAML
<Grid>
<TextBox HorizontalAlignment="Left" Name="tbName" Margin="450,148,0,0" Text="{Binding Value}"
Foreground="{Binding ValueColor}" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
</Grid>
//MainWindow.xaml.cs
public partial class MainWindow : Window
{
MainViewModel mainViewModel=null;
public MainWindow()
{
InitializeComponent();
mainViewModel = new MainViewModel();
this.DataContext = mainViewModel;
}
private void Button_Click(object sender, RoutedEventArgs e) //事件驱动有控件参与
{
mainViewModel.Value = "100";
}
}
//MainViewWindow,cs
public class MainViewModel:INotifyPropertyChanged //数据驱动
{
public event PropertyChangedEventHandler PropertyChanged; //订阅的方式更新数据
private string _Value= "WPFNETS";
public string Value
{
get { return _Value; }
set { _Value = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Value"));
if (value == "100")
ValueColor = Brushes.Red;
}
}
private Brush _valueColor = Brushes.Orange;
public Brush ValueColor
{
get { return _valueColor; }
set { _valueColor = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ValueColor"));
}
}
}
Basic operation of the MVVM pattern
MVVM pattern
- Model: data model, View (interface), ViewModel (business logic processing)
Data Binding in MVVM Pattern
<ItemsControl Grid.Column="1" ItemsSource="{Binding ValueList}" Background="Khaki">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="20,20">
<TextBlock Text="{Binding Value}"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
//-------------------------------------------//
// MainViewModel.cs
//-------------------------------------------//
public List<ValueModel> ValueList { get; set; } = new List<ValueModel>
{
new ValueModel{ Value="123",Name="aaa" },
new ValueModel{ Value="456",Name="bbb" },
};
//-------------------------------------------//
// ValueModel.cs
//-------------------------------------------//
public class ValueModel
{
public string Value { get; set; }
public string Name { get; set; }
}
Behavior binding in MVVM pattern
//MainWindow.XAML
<Grid>
<Button Content="Button" HorizontalAlignment="Center" Margin="0,29,0,0" VerticalAlignment="Top"
Command="{Binding VlaueCommand}" CommandParameter="123" /> //Button 行为绑定
//<!--UpdateSourceTrigger=PropertyChanged 当Value 变化时,实时更新-->
<TextBox HorizontalAlignment="Left" x:Name="tbName" Margin="450,148,0,0"
Text="{Binding Value,UpdateSourceTrigger=PropertyChanged}"
Foreground="{Binding ValueColor}"
TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<TextBlock HorizontalAlignment="Center" Text="UserName" TextWrapping="Wrap" VerticalAlignment="Center"/>
</Grid>
//-------------------------------------------//
// MainViewModel.cs
//-------------------------------------------//
public class MainViewModel:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
//TextBox Text={"binding Value"}
private string _Value= "WPFNETS"; /
public string Value
{
get { return _Value; }
set { _Value = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Value"));
if (value == "100")
ValueColor = Brushes.Red;
(this.VlaueCommand as CommandBase).RaiseCanChanged(); //强转为 CommandBase
}
}
//TextBox Foreground="{Binding ValueColor}"
private Brush _valueColor = Brushes.Orange;
public Brush ValueColor
{
get { return _valueColor; }
set { _valueColor = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ValueColor"));
}
}
//Button Command="{Binding VlaueCommand}" 行为绑定
private ICommand _valueCommand ;
public ICommand VlaueCommand
{
get {
if (_valueCommand == null)
{
//Button 行为事件执行 ValueCommandAciton 将TextBox Value 修改为100
_valueCommand = new CommandBase() { DoAction = new Action<object>(ValueCommandAciton),
DoCanExecute=new Func<object, bool>(CanExecute)};
}
return _valueCommand; }
set { _valueCommand = value; }
}
private void ValueCommandAciton(object obj)
{
Value = "100";
}
private bool CanExecute(object obj)
{
return !string.IsNullOrEmpty(Value);
}
}
//-------------------------------------------//
// CommandBase.cs
//-------------------------------------------//
class CommandBase : ICommand
{
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return DoCanExecute.Invoke(parameter)==true;
}
public void Execute(object parameter) //xaml CommandParemeter="123" 点击事件发生进入
{
//控制逻辑
DoAction?.Invoke(parameter);
}
public Action<object> DoAction { set; get; } //Action 委托
public Func<object, bool> DoCanExecute { set; get; } //Func 委托
public void RaiseCanChanged(){
CanExecuteChanged?.Invoke(this,new EventArgs());
}
}