WPF 高级篇 MVVM (MVVMlight)绑定

时间:2022-11-22 00:39:15


我们这边来实现MvvMlight 主界面功能 实现数据显示 

WPF 高级篇 MVVM (MVVMlight)绑定

我们看界面元素 一个ListView    4个值固定的TextBlock 对应下面4个更具选择动态变化的TextBlock 三个Button 

那么 分析一下需要的绑定对象

一个是Listview 需要一个 集合对象 

选中集合对象 我们要把数据显示到右面 4个TextBlock 里  那么我们还需要被选中的对象

三个Button 就有三个事件

我们整理一下 一个集合  一个选择对象 三个事件

我们开始写Mainwindow 绑定

private ObservableCollection<Book> _allBooks;

public ObservableCollection<Book> AllBooks
{
get { return _allBooks; }
set { Set(ref _allBooks ,value); }
}

private Book selectedBook;

public Book SelectedBook
{
get { return selectedBook; }
set { Set(ref selectedBook , value);
EditBookCommand.RaiseCanExecuteChanged();
DeleteBookCommand.RaiseCanExecuteChanged();
}
}

private RelayCommand addBookCommand;

public RelayCommand AddBookCommand
{
get { return addBookCommand; }
set { addBookCommand = value; }
}

private RelayCommand<Book> editBookCommand;

public RelayCommand<Book> EditBookCommand
{
get { return editBookCommand; }
set { editBookCommand = value; }
}

public RelayCommand<Book> DeleteBookCommand { get; set; }

ObservableCollection 集合

是WPF 中 自带对象动态改变通知功能 就是用这个对象绑定数据 不需要管 集合参数变更后如何通知界面 都是自动的

属性通知

功能: 

Set(ref 参数,值);

在正常的WPF开发中 需要类继承InotifyPropertyChanged接口  实现通知功能

在MVVMlight中  ViewModel类 需要继承ViewModelBase 在属性中用Set(ref 属性,值) 即可

事件

就更简单了 直接用 relayCommand 定义方法  用参数 用RelayCommand <参数>

在构造函数里 

注册事件 并注册事件方法

MainViewModel

public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
AllBooks = new ObservableCollection<Book>(BookData.GetBook());
}
private ObservableCollection<Book> _allBooks;

public ObservableCollection<Book> AllBooks
{
get { return _allBooks; }
set { Set(ref _allBooks, value); }
}

private Book selectedBook;

public Book SelectedBook
{
get { return selectedBook; }
set
{
Set(ref selectedBook, value);
EditBookCommand.RaiseCanExecuteChanged();
DeleteBookCommand.RaiseCanExecuteChanged();
}
}

private RelayCommand addBookCommand;

public RelayCommand AddBookCommand
{
get { return addBookCommand; }
set { addBookCommand = value; }
}

private RelayCommand<Book> editBookCommand;

public RelayCommand<Book> EditBookCommand
{
get { return editBookCommand; }
set { editBookCommand = value; }
}

public RelayCommand<Book> DeleteBookCommand { get; set; }
}

ViewModelLocator

/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

if (ViewModelBase.IsInDesignModeStatic)
{
// Create design time view services and models
SimpleIoc.Default.Register<IDataService, DesignDataService>();
}
else
{
// Create run time view services and models
SimpleIoc.Default.Register<IDataService, DataService>();
}

SimpleIoc.Default.Register<MainViewModel>();
}

public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}

public static void Cleanup()
{
// TODO Clear the ViewModels
}

APP中用Key方式 全局ViewModelLocator  类

<Application x:Class="WpfApp1.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp1"
StartupUri="Views/MainWindow.xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:WpfApp1.ViewModel"
d1p1:Ignorable="d" xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Application.Resources>
<ResourceDictionary>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</ResourceDictionary>
</Application.Resources>
</Application>

界面绑定

这里要单独并且 严肃的说一下  DataContext 上下文引用 全局共享的Locator

View(dataContext通过类 key Locator)  --- APP( 定义全局 key 为Locator) ---ViewModel (Locator的类)

链接起来了~~~~

DataContext="{Binding Main, Source={StaticResource Locator}}"
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<Border
Grid.ColumnSpan="2"
Background="#EEE"
BorderBrush="#ABADB3"
BorderThickness="1">
<TextBlock
x:Name="txtTitle"
Margin="10,0,0,0"
VerticalAlignment="Center"
FontSize="16"
FontWeight="SemiBold"
Text="Book Manager" />
</Border>

<ListView
Grid.Row="1"
BorderThickness="1,0,1,1"
ItemsSource="{Binding AllBooks}"
SelectedItem="{Binding SelectedBook}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock FontSize="16" Text="{Binding Title}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

<Grid Grid.Row="1" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Margin="10">
<StackPanel Orientation="Horizontal">
<Button
Padding="5"
Command="{Binding AddBookCommand}"
Content="添加" />
<Button
Margin="10,0,0,0"
Padding="5"
Command="{Binding EditBookCommand}"
CommandParameter="{Binding SelectedBook}"
Content="编辑" />
<Button
Margin="10,0,0,0"
Padding="5"
Command="{Binding DeleteBookCommand}"
CommandParameter="{Binding SelectedBook}"
Content="删除" />
</StackPanel>
</StackPanel>
<StackPanel Grid.Row="1" Margin="10,0,10,10"
<TextBlock Text="标题" />
<TextBlock Margin="0,0,0,12" Text="{Binding SelectedBook.Title}" />
<TextBlock Text="作者" />
<TextBlock Margin="0,0,0,12" Text="{Binding SelectedBook.Author}" />
<TextBlock Text="描述" />
<TextBlock
Margin="0,0,0,12"
Text="{Binding SelectedBook.Description}"
TextWrapping="Wrap" />
<TextBlock Text="页码数" />
<TextBlock Margin="0,0,0,12" Text="{Binding SelectedBook.Pages}" />
</StackPanel>
</Grid>
</Grid>

数据绑定 ListView 绑定集合 和SelectedItem 

  ItemsSource="{Binding AllBooks}"
  SelectedItem="{Binding SelectedBook}">

界面效果

WPF 高级篇 MVVM (MVVMlight)绑定