我想在画布中间用 mvvm 图案画一个形状。
在后面的代码中,我通过使用 ActualWidth 和 ActualHeight 属性达到了中间点。
但是我在 MVVM 中执行此操作时遇到困难。我如何从 XAML 实现 ActualWidth 和 ActualHeight 属性?
这些是 XAML 代码:
<Window x:Class="CanvasSampleMvvm.View.MainView"
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:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:CanvasSampleMvvm.View"
xmlns:model="clr-namespace:CanvasSampleMvvm.Model"
xmlns:vm="clr-namespace:CanvasSampleMvvm.ViewModel"
mc:Ignorable="d"
Title="MainView" Height="450" Width="800">
<Window.Resources>
<vm:MainViewVM x:Key="vm"/>
</Window.Resources>
<Grid DataContext="{StaticResource vm}">
<ItemsControl ItemsSource="{Binding Path=Shapes}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type model:mShape}">
<Path Data="{Binding Geometry}" Stroke="{Binding Stroke}" Fill="{Binding Fill}" RenderTransform="{Binding Transform}" />
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas ClipToBounds="True" Background="Transparent" DataContext="{StaticResource vm}">
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=XPos}" />
<Setter Property="Canvas.Top" Value="{Binding Path=YPos}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
</Window>
这些是 MainView 模型代码:
public class MainViewVM : INotifyPropertyChanged
{
public ObservableCollection<mShape> Shapes { get; } = new ObservableCollection<mShape>();
public MainViewVM()
{
// XPos abd YPos values has to be center coordinates of canvas panel
Shapes.Add(new mShape
{
XPos = 100,
YPos = 100,
Stroke = new SolidColorBrush(Color.FromArgb(0xFF, 0x66, 0x66, 0x66)),
Geometry = new EllipseGeometry { RadiusX = 50, RadiusY = 50 },
Fill = (SolidColorBrush)new BrushConvert,r().ConvertFrom("#D3D3D3")
});
}
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
这是模型类:
public class mShape
{
public double XPos { get; set; }
public double YPos { get; set; }
public Geometry Geometry { get; set; }
public Brush Stroke { get; set; }
public Brush Fill { get; set; }
}
如何从 XAML 实现 ActualWidth 和 ActualHeight 属性?
您需要实现一些代码来跟踪视图中这些属性的更改并设置视图模型属性。
您可以查看 GitHub 上的 SizeObserver 实现,了解可以实现此目的的示例。
它实现了您可以在 XAML 标记中绑定到的附加属性:
<Canvas SizeObserver.Observe="True"
SizeObserver.ObservedWidth="{Binding YourViewModelWidthProperty, Mode=OneWayToSource}"
SizeObserver.ObservedHeight="{Binding YourViewModelHeightProperty, Mode=OneWayToSource}">
... />