忘记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辅助类):
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));
}));
}
}
结果:
- 单击并拖动号在左侧并将其拖放到任意正方形。号码将被放置在广场内。
- 移动滑块并注意
UniformGrid
的行和列是如何变化的。全部通过DataBinding。
- 不需要在代码中创建或操作UI元素。全部通过DataBinding完成。
- 决议独立性。这是WPF提供的。一切都被拉伸到包含的窗口大小。
- MVVM = “Just Simple,Simple Properties and
INotifyPropertyChanged
”。这就是如何在WPF中编程。不需要复杂的事件“听众”(不管那是什么)或任何这样的糟糕的东西。
- 只需将我的代码复制并粘贴到
File -> New -> WPF Application
中即可自行查看结果。
- 让我知道你是否需要进一步的帮助。
- WPF Rocks。其他一切都没有或完全吸引。
尺寸调整机制是wpf的优点之一,所以如果你问是否可以做到,那么答案是肯定的,你有什么尝试吗? – makc
你可能想看看[UniformGrid](http://msdn.microsoft.com/en-us/library/ms612624.aspx)。 – Clemens
@ makc不是真的,因为我不知道该怎么做。 –