忘记java。它又旧又笨又没用。它甚至没有属性。更不用说 WPF 提供的DataBinding功能了,更不用说 LinQ 的美妙之处了。
这是我对您描述的内容的看法:
<Window x:Class="MiscSamples.SquaresGameSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Forget java. It's a crappy dinousaur." Height="300" Width="300">
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="2">
<TextBlock Text="Rows:"/>
<Slider Maximum="100" Minimum="10" Value="{Binding Rows}" Width="200"/>
<TextBlock Text="Columns:"/>
<Slider Maximum="100" Minimum="10" Value="{Binding Columns}" Width="200"/>
</StackPanel>
<ListBox Margin="0,0,20,0" Width="50" DockPanel.Dock="Left" ItemsSource="{Binding Numbers}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="OnItemMouseDown"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<ItemsControl ItemsSource="{Binding Squares}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="{Binding Rows}" Columns="{Binding Columns}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="DarkGray" BorderThickness="1"
Background="#05FFFFFF" AllowDrop="True"
Drop="OnDrop">
<TextBlock VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="{Binding Value}"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DockPanel>
</Window>
代码背后:
public partial class SquaresGameSample : Window
{
public SquaresGameSample()
{
InitializeComponent();
DataContext = new SquaresGameViewModel();
}
private void OnDrop(object sender, DragEventArgs e)
{
var item = sender as FrameworkElement;
if (item == null)
return;
var square = item.DataContext as Square;
if (square == null)
return;
var number = (int)e.Data.GetData(typeof (int));
square.Value = number;
}
private void OnItemMouseDown(object sender, MouseEventArgs e)
{
var item = sender as ListBoxItem;
if (item == null)
return;
DragDrop.DoDragDrop(sender as DependencyObject, item.DataContext, DragDropEffects.Move);
}
}
视图模型:
public class SquaresGameViewModel: PropertyChangedBase
{
private ObservableCollection<Square> _squares;
public ObservableCollection<Square> Squares
{
get { return _squares ?? (_squares = new ObservableCollection<Square>()); }
}
private int _rows;
public int Rows
{
get { return _rows; }
set
{
_rows = value;
OnPropertyChanged("Rows");
CreateSquares();
}
}
private int _columns;
public int Columns
{
get { return _columns; }
set
{
_columns = value;
OnPropertyChanged("Columns");
CreateSquares();
}
}
public List<int> Numbers { get; set; }
public SquaresGameViewModel()
{
_rows = 10;
_columns = 10;
Numbers = Enumerable.Range(1, 20).ToList();
CreateSquares();
}
private void CreateSquares()
{
Squares.Clear();
Enumerable.Range(0, Rows)
.SelectMany(x => Enumerable.Range(0, Columns)
.Select(y => new Square { Row = x, Column = y }))
.ToList().ForEach(Squares.Add);
}
}
数据项:
public class Square: PropertyChangedBase
{
public int Row { get; set; }
public int Column { get; set; }
private int _value;
public int Value
{
get { return _value; }
set
{
_value = value;
OnPropertyChanged("Value");
}
}
}
PropertyChangedBase(MVVM Helper 类):
public class PropertyChangedBase:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
Application.Current.Dispatcher.BeginInvoke((Action) (() =>
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}));
}
}
结果:
![在此处输入图像描述](https://i.stack.imgur.com/iSiyB.png)
- 单击并拖动左侧的数字并将它们放在任何正方形上。号码将被放置在 Square 内。
- 移动滑块并注意
UniformGrid
的行和列如何变化。全部通过数据绑定。
- 无需在代码中创建或操作 UI 元素。一切都是通过 DataBinding 完成的。
- 分辨率独立性。这就是 WPF 提供的。一切都被拉伸到包含的窗口大小。
- MVVM = “只是简单,简单的属性和
INotifyPropertyChanged
”。这就是在 WPF 中编程的方法。不需要复杂的事件“听众”(不管是什么)或任何类似的蹩脚的东西。
- 只需将我的代码复制并粘贴到 a 中
File -> New -> WPF Application
,然后自己查看结果。
- 如果您需要进一步的帮助,请告诉我。
- WPF 摇滚。其他一切要么没有,要么完全糟透了。