这将是您屏幕截图的 WPF 方法:
<Window x:Class="WpfApplication4.Window9"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window9" Height="300" Width="500">
<ItemsControl ItemsSource="{Binding Columns}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisConverter"/>
</DataTemplate.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="25"/>
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<!-- This is your Key image, I used a rectangle instead, you can change it -->
<Rectangle Fill="Yellow" Visibility="{Binding IsPrimaryKey, Converter={StaticResource BoolToVisConverter}}" Margin="2"/>
<CheckBox IsChecked="{Binding IsSelected}" Grid.Column="1"/>
<TextBlock Text="{Binding Name}" Grid.Column="2"/>
<ComboBox ItemsSource="{Binding SortOrders}" SelectedItem="{Binding SortOrder}" Grid.Column="3" Margin="2"/>
<Button Content="Up" Grid.Column="4" Margin="2"
Command="{Binding DataContext.MoveUpCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=ItemsControl}}"
CommandParameter="{Binding}"/>
<Button Content="Down" Grid.Column="5" Margin="2"
Command="{Binding DataContext.MoveDownCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=ItemsControl}}"
CommandParameter="{Binding}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
代码背后:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using InduraClientCommon.MVVM;
using System.Collections.ObjectModel;
namespace WpfApplication4
{
public partial class Window9 : Window
{
public Window9()
{
InitializeComponent();
var vm = new ColumnListViewModel();
vm.Columns.Add(new ColumnViewModel() { IsPrimaryKey = true, Name = "Customer ID", SortOrder = SortOrder.Ascending });
vm.Columns.Add(new ColumnViewModel() {Name = "Customer Name", SortOrder = SortOrder.Descending});
vm.Columns.Add(new ColumnViewModel() {Name = "Customer Age", SortOrder = SortOrder.Unsorted});
DataContext = vm;
}
}
}
视图模型:
public class ColumnListViewModel: ViewModelBase
{
private ObservableCollection<ColumnViewModel> _columns;
public ObservableCollection<ColumnViewModel> Columns
{
get { return _columns ?? (_columns = new ObservableCollection<ColumnViewModel>()); }
}
private DelegateCommand<ColumnViewModel> _moveUpCommand;
public DelegateCommand<ColumnViewModel> MoveUpCommand
{
get { return _moveUpCommand ?? (_moveUpCommand = new DelegateCommand<ColumnViewModel>(MoveUp, x => Columns.IndexOf(x) > 0)); }
}
private DelegateCommand<ColumnViewModel> _moveDownCommand;
public DelegateCommand<ColumnViewModel> MoveDownCommand
{
get { return _moveDownCommand ?? (_moveDownCommand = new DelegateCommand<ColumnViewModel>(MoveDown, x => Columns.IndexOf(x) < Columns.Count)); }
}
private void MoveUp(ColumnViewModel item)
{
var index = Columns.IndexOf(item);
Columns.Move(index, index - 1);
MoveUpCommand.RaiseCanExecuteChanged();
MoveDownCommand.RaiseCanExecuteChanged();
}
private void MoveDown(ColumnViewModel item)
{
var index = Columns.IndexOf(item);
Columns.Move(index, index + 1);
MoveUpCommand.RaiseCanExecuteChanged();
MoveDownCommand.RaiseCanExecuteChanged();
}
}
public class ColumnViewModel: ViewModelBase
{
private bool _isPrimaryKey;
public bool IsPrimaryKey
{
get { return _isPrimaryKey; }
set
{
_isPrimaryKey = value;
NotifyPropertyChange(() => IsPrimaryKey);
}
}
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
NotifyPropertyChange(() => IsSelected);
}
}
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
NotifyPropertyChange(() => Name);
}
}
private List<SortOrder> _sortOrders;
public List<SortOrder> SortOrders
{
get { return _sortOrders ?? (_sortOrders = Enum.GetValues(typeof(SortOrder)).OfType<SortOrder>().ToList()); }
}
private SortOrder _sortOrder;
public SortOrder SortOrder
{
get { return _sortOrder; }
set
{
_sortOrder = value;
NotifyPropertyChange(() => SortOrder);
}
}
}
public enum SortOrder {Unsorted, Ascending, Descending}
}
这是它在我的屏幕上的样子:
正如您在上面的示例中看到的,我绝不会在代码中操作或创建 UI 元素,因为这实际上没有必要。每当您需要与屏幕上显示的信息进行交互时,您都与ViewModel
s 而不是View
. 这是 WPF 使 UI 和应用程序逻辑之间的关注点清晰分离成为可能,而这在其他框架中是完全不存在的。在 WPF 中执行任何类型的 N 元素 UI 时,请将此方法视为事实上的默认方法。
编辑:
这种方法相对于一种方法的优点classic
:
- 无需在代码中操作复杂的 WPF 类(IE UI 元素)即可显示/从屏幕获取数据(只需简单、简单的属性和 INotifyPropertyChanged)
- 更好地缩放(UI 可以是任何东西,只要它尊重 ViewModel 属性,您可以将 ComboBox 更改为旋转的 3d 粉色大象,每只脚都有一个排序顺序。
- 无需导航视觉树来查找天知道在哪里的元素。
- 什么都不需要
foreach
。只是Select
将您的数据(从您获得的任何数据源)转换为
ViewModel
列表的简单方法。
底线:如果您使用 WPF 方法,WPF 比目前存在的任何其他东西都更简单和更好。