Wpf属性绑定vs命令
我创建了两个用户控件,一个在画布上显示我的数据/视图模型集合的二维笛卡尔地图。另一个是一栏滚动图像库,它为每个数据模型显示一个图像。(片段化)映射基于:Wpf属性绑定vs命令,wpf,binding,command,Wpf,Binding,Command,我创建了两个用户控件,一个在画布上显示我的数据/视图模型集合的二维笛卡尔地图。另一个是一栏滚动图像库,它为每个数据模型显示一个图像。(片段化)映射基于: <ItemsControl ItemsSource="{Binding Defects}" ItemTemplateSelector="{StaticResource IconSelector}"> <!-- ItemsPanelTemplate --&
<ItemsControl
ItemsSource="{Binding Defects}"
ItemTemplateSelector="{StaticResource IconSelector}">
<!-- ItemsPanelTemplate -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas x:Name="MapCanvas" Height="10000"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- ItemContainerStyle -->
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Top" Value="{Binding Y}" />
<Setter Property="Canvas.Left" Value="{Binding X}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
<ScrollViewer Name="ScrollContainer"
Grid.Column="1" PanningMode="VerticalOnly"
VerticalScrollBarVisibility="Visible"
HorizontalScrollBarVisibility="Visible"
Background="White">
<ItemsControl Name="ItemsContainer" ItemsSource="{Binding Defects}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="5" BorderBrush="Gray" Margin="2">
<Image Source="{Binding ImageUrl}" Margin="2"></Image>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
图像库(同样是片段化的)基于:
<ItemsControl
ItemsSource="{Binding Defects}"
ItemTemplateSelector="{StaticResource IconSelector}">
<!-- ItemsPanelTemplate -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas x:Name="MapCanvas" Height="10000"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- ItemContainerStyle -->
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Top" Value="{Binding Y}" />
<Setter Property="Canvas.Left" Value="{Binding X}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
<ScrollViewer Name="ScrollContainer"
Grid.Column="1" PanningMode="VerticalOnly"
VerticalScrollBarVisibility="Visible"
HorizontalScrollBarVisibility="Visible"
Background="White">
<ItemsControl Name="ItemsContainer" ItemsSource="{Binding Defects}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="5" BorderBrush="Gray" Margin="2">
<Image Source="{Binding ImageUrl}" Margin="2"></Image>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
现在我想给我的数据的这两个视图添加一些同步。也就是说,当单击地图上的一个图标时,我希望图库滚动到相应的图像。
我已尝试向两个控件添加依赖项属性,以指向选定的索引。这并不是我真正想要的,因为我想要一些额外的灵活性。有时我希望滚动与动画一起完成,有时我希望立即同步选定的索引。
因此,我尝试将自定义命令BringIntoView添加到viewmodel中。此命令接受布尔输入,以指定是否必须使用动画执行操作。我可以将datatemplate绑定到我的自定义命令,并且只要单击地图上的图标,地图控件就会正确地调用自定义命令上的execute
但是我被困在gallery端,如何将此命令绑定到某个代码隐藏方法,或者绑定到控件上的某个其他方法?命令绑定不起作用,因为它不允许对命令进行动态绑定。以下内容引发编译时错误,因为CommandBinding上的Command属性不是依赖项属性:
<UserControl.CommandBindings>
<CommandBinding Command="{Binding BringIntoView}" Executed="OnBringIntoViewExecuted"/>
</UserControl.CommandBindings>
我可以添加一个静态命令并直接引用该命令,但这至少会将视图绑定到viewmodel命令。那么,如何实现这种级别的命令链接,同时保持与视图的解耦呢
换句话说,WPF依赖属性系统允许绑定两个UI控件的两个UI特定属性。如何实现命令/事件的相同功能?也就是说,来自用户控件的UI事件/命令连接到另一个UI控件的方法/命令?我找到了解决此设计问题的方法。与依赖属性类似,自定义控件也可以公开自定义命令。由于控件直接公开的命令(与viewmodel公开的命令相反)是特定于UI的,因此最适合使用RoutedUiCommand而不是自定义ICommand实现。RouteDicCommand可以作为静态属性公开,就像DependencyProperty一样。在我的示例中,gallery控件公开了一个静态BringIntoView命令,如下所示:
public partial class DefectGallery {
// the control exposes the following commands:
public static readonly RoutedUiCommand BringIntoView = new RoutedUiCommand;
// the control exposes the following depdendency properties:
public static readonly DependencyProperty ScrollSpeedProperty = DependencyProperty.Register(...);
...
}
该命令绑定到DefectGallery控件的xaml文件中的代码隐藏:
<UserControl.CommandBindings>
<CommandBinding Command="{x:static local:DefectGallery.BringIntoView}" Executed="OnBringIntoViewExecuted"/>
</UserControl.CommandBindings>
最后,需要一些其他控件来触发bringintoview命令。例如,它可以是WPF提供的命令源,如按钮。在我的例子中,我在map控件上实现了ICommandSource接口,以便允许指定一个自定义命令,该命令在每次单击map上的图标时执行。我现在可以使用xaml中的映射控件(上面的第一个片段),如下所示:
<MapControl
Command="{x:static local:DefectGallery.BringIntoView}"
CommandTarget="{Binding ElementName=defectGalleryInstance}"
/>
因此,我可以有效地使用声明性xaml从另一个控件“调用”控件
现在,这似乎和添加依赖属性一样基本,所以我很惊讶我没有找到这方面的指导方针。在我看来,控件公开属性和命令是很自然的;我认为这两个界面是UI控件与其他UI组件的“接口”,而视图模型绑定是应用层的接口。哦,WPF适合不同的使用方法,您只需找到适合您/您的应用程序的方法