我目前在我的一个应用中正在使用MVVM
模式,更具体地说,我正在使用MVVMLight
框架。在其中一个页面中,我将看到一个屏幕,用户可以在其中输入width
和length
来绘制矩形,没有太多的代码逻辑,因此,我正在考虑将所有代码放入代码隐藏,因为此屏幕中将发生的大多数事与UI相关。
在这种情况下使用后台代码有意义吗?如果不是,您将如何构造代码以使用MVVM模式?在这种情况下,您将把什么放在ViewModel
中,以及将代码放在什么后面?
这是不使用MVVM的代码。
<Window x:Class="DrawingRectangles.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DrawingRectangles"
mc:Ignorable="d"
Title="MainWindow" Height="531.798" Width="782.115">
<Grid Name="MyGrid" Width="480" Height="240" Margin="27,23,267,174">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="59*"/>
<ColumnDefinition Width="421*"/>
</Grid.ColumnDefinitions>
<Canvas Name="MyCanvas" Background="#FFF1F0F0" Margin="10" Grid.ColumnSpan="2"/>
<Grid Margin="10,235,10,-92" Background="WhiteSmoke" Grid.ColumnSpan="2">
<Button x:Name="drawButton" Content="Draw" Click="drawButton_Click"/>
<Button x:Name="resetButton" Content="Reset" Click="resetButton_Click"/>
<TextBox x:Name="textBoxPartWidth"/>
<TextBox x:Name="textBoxPartLength"/>
</Grid>
</Grid>
</Window>
namespace DrawingRectangles
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void drawButton_Click(object sender, RoutedEventArgs e)
{
clearScreen();
int xParts = 10;
int yParts = 10;
for (int i = 0; i < xParts; i++) {
for (int j = 0; j < yParts; j++) {
// Create a rectangle.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = Convert.ToDouble(textBoxPartLength.Text);
myRectangle.Height = Convert.ToDouble(textBoxPartWidth.Text);
myRectangle.Margin = new Thickness((Convert.ToInt32(myRectangle.Width) + 1) * i, (Convert.ToInt32(myRectangle.Height) + 1) * j, 0, 0);
myRectangle.Fill = new SolidColorBrush(Color.FromArgb(170, 51, 51, 255));
MyCanvas.Children.Add(myRectangle);
}
}
}
private void resetButton_Click(object sender, RoutedEventArgs e)
{
MyCanvas.Children.Clear();
}
private void clearScreen()
{
MyCanvas.Children.Clear();
}
}
}
答案 0 :(得分:1)
视图中的Button
应该绑定到视图模型的ICommand
属性。单击Button
时将执行该命令。请参阅this blog post,以获取有关如何在MVVM应用程序中处理事件的信息。在MvvmLight中,ICommand
实现称为RelayCommand
。
您还应该将Text
的{{1}}属性绑定到视图模型的两个源属性,并且视图中的TextBoxes
元素应替换为Canvas
您绑定到视图模型中定义的对象的集合。
请参考以下示例代码。
型号:
ItemsControl
查看:
public class Model
{
public int Width { get; set; }
public int Height { get; set; }
public Thickness Margin { get; set; }
public Brush Fill { get; set; }
}
查看模型:
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="#FFF1F0F0" Margin="10" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Width="{Binding Width}"
Height="{Binding Height}"
Margin="{Binding Margin}"
Fill="{Binding Fill}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Content="Draw" Command="{Binding DrawCommand}" />
<Button Content="Reset" Command="{Binding ResetCommand}" />
<TextBox Text="{Binding Width}"/>
<TextBox Text="{Binding Height}"/>
在此示例中,所有应用程序逻辑均已移至其所属的视图模型。视图的代码隐藏类中没有逻辑。
还要注意,视图模型创建public class ViewModel
{
public ViewModel()
{
DrawCommand = new RelayCommand(Draw);
ResetCommand = new RelayCommand(Clear);
}
public ObservableCollection<Model> Items { get; } = new ObservableCollection<Model>();
public RelayCommand DrawCommand { get; }
public RelayCommand ResetCommand { get; }
public int Width { get; set; }
public int Height { get; set; }
private void Draw()
{
Clear();
int xParts = 10;
int yParts = 10;
for (int i = 0; i < xParts; i++)
{
for (int j = 0; j < yParts; j++)
{
Model model = new Model();
model.Width = Width;
model.Height = Height;
model.Margin = new Thickness((model.Width + 1) * i, (model.Height + 1) * j, 0, 0);
model.Fill = new SolidColorBrush(Color.FromArgb(170, 51, 51, 255));
Items.Add(model);
}
}
}
private void Clear()
{
Items.Clear();
}
}
对象的实例,而不是创建Model
元素。通常,在视图模型类中引用UI元素是一种不好的做法。 Rectangle
元素由Rectangle
创建。请在视图中查看ItemsControl
。