获取选定的 ItemsControl Item
Getting selected ItemsControl Item
目前正在创建我的 windows 10 应用程序,我正在尝试按照 mvvm 模式在 canvas 上移动一个矩形。下面的代码有效,但我通过在我的视图模型 PointerDragEvent 中使用 uielemnt 破坏了 mvvm。
Dim rec = TryCast(e.OriginalSource, Button)
Dim selrecitem = TryCast(rec.DataContext, RectItem)
问题
有没有非 hacky/proper 的方法可以做到这一点?
如何检索我单击的项目并将其传递给我的视图模型?
canvas 上的所有项目都将动态创建。
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App11"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity" xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
x:Class="App11.MainPage"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.DataContext>
<local:myviewmodel/>
</Grid.DataContext>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="8*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="11*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ItemsControl x:Name="itemsControl" Grid.Column="1" Grid.Row="1" ItemsSource="{Binding myrectangles, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="ManipulationDelta">
<Core:CallMethodAction TargetObject="{Binding Mode=OneWay}" MethodName="PointerDrag"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="White">
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button x:Name="PageItem" Background="Transparent" BorderBrush="DodgerBlue" Width="{Binding Width}" Height="{Binding Height}" ManipulationMode="TranslateX, TranslateY" IsHitTestVisible="{Binding IsChecked, ElementName=SelectToolButton, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Command="{Binding SendMyDC, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<Button.RenderTransform>
<CompositeTransform TranslateX="{Binding X}" TranslateY="{Binding Y}"/>
</Button.RenderTransform>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
视图模型
Public Class myviewmodel
Implements INotifyPropertyChanged
Private Sub NotifyPropertyChanged(Optional propertyName As String = "")
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private _myrectangles As New ObservableCollection(Of RectItem)
Public Property myrectangles As ObservableCollection(Of RectItem)
Get
Return _myrectangles
End Get
Set(value As ObservableCollection(Of RectItem))
_myrectangles = value
NotifyPropertyChanged()
End Set
End Property
Public Sub New()
Dim newrect As New RectItem
newrect.Height = 100
newrect.Width = 150
newrect.X = 50
newrect.Y = 50
_myrectangles.Add(newrect)
End Sub
Public Sub PointerDrag(sender As Object, e As ManipulationDeltaRoutedEventArgs)
Dim dx_point = e.Delta.Translation.X
NotifyPropertyChanged()
Dim dy_point = e.Delta.Translation.Y
NotifyPropertyChanged()
Dim rec = TryCast(e.OriginalSource, Button)
Dim selrecitem = TryCast(rec.DataContext, RectItem)
selrecitem.X += dx_point
selrecitem.Y += dy_point
End Sub
End Class
RectItemClass
Public Class RectItem
Implements INotifyPropertyChanged
Private Sub NotifyPropertyChanged(Optional propertyName As String = "")
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Public Property X As Double
Get
Return m_X
End Get
Set
m_X = Value
NotifyPropertyChanged()
End Set
End Property
Private m_X As Double
Public Property Y As Double
Get
Return m_Y
End Get
Set
m_Y = Value
NotifyPropertyChanged()
End Set
End Property
Private m_Y As Double
Public Property Width As Double
Get
Return m_Width
End Get
Set
m_Width = Value
NotifyPropertyChanged()
End Set
End Property
Private m_Width As Double
Public Property Height As Double
Get
Return m_Height
End Get
Set
m_Height = Value
NotifyPropertyChanged()
End Set
End Property
Private m_Height As Double
End Class
编辑 #1 我没有使用项目控件,而是使用 ListView/Listbox 并将所选项目绑定到我的 vewimodel 中的 属性。对于列表视图,在使项目呈现器与其呈现的项目和列表框对齐时存在一些问题,指针向上事件不会触发。
<ListView x:Name="itemsControl" Grid.Column="1" Grid.Row="1" ItemsSource="{Binding myrectangles, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" Background="#FFF2F2F2" SelectedItem="{Binding selectedrec, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="ManipulationDelta">
<Core:CallMethodAction TargetObject="{Binding Mode=OneWay}" MethodName="PointerDrag"/>
</Core:EventTriggerBehavior>
<Core:EventTriggerBehavior EventName="PointerPressed">
<Core:CallMethodAction TargetObject="{Binding Mode=OneWay}" MethodName="PointerPressed"/>
</Core:EventTriggerBehavior>
<!--<Core:EventTriggerBehavior EventName="PointerReleased">
<Core:CallMethodAction TargetObject="{Binding Mode=OneWay}" MethodName="Up"/>
</Core:EventTriggerBehavior>-->
</Interactivity:Interaction.Behaviors>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="White">
</Canvas>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<!--<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>-->
<ListView.ItemTemplate>
<DataTemplate>
<Rectangle x:Name="PageItem" Width="{Binding Width}" Height="{Binding Height}" Fill="Transparent" Stroke="DodgerBlue" ManipulationMode="TranslateX, TranslateY" IsHitTestVisible="{Binding IsChecked, ElementName=SelectToolButton, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" >
<Rectangle.RenderTransform>
<CompositeTransform TranslateX="{Binding X}" TranslateY="{Binding Y}"/>
</Rectangle.RenderTransform>
</Rectangle>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
已更新 ViewModel
Public _selectedrec As New RectItem
Public Property selectedrec As RectItem
Get
Return _selectedrec
End Get
Set(value As RectItem)
_selectedrec = value
NotifyPropertyChanged()
End Set
End Property
Public Sub PointerDrag(sender As Object, e As ManipulationDeltaRoutedEventArgs)
Dim dx_point = e.Delta.Translation.X
NotifyPropertyChanged()
Dim dy_point = e.Delta.Translation.Y
NotifyPropertyChanged()
selectedrec.X += dx_point
NotifyPropertyChanged()
selectedrec.Y += dy_point
NotifyPropertyChanged()
End Sub
问题示例
无 itemcontainerstyle - 尝试将对象捕捉拖动到 canvas
的 0,0 时
MyHalfFix - 取消注释 ItemContainerStyle - 一切正常,我的目标是什么
在实际程序中实现时的整体问题
红色的Item是listviewitem presenter。它被正确绘制,但定位与绘制的矩形不对齐,它总是捕捉到 canvas 的点 0,0。我可以使它透明,但正如您在绘制矩形时也看到的那样,它没有正确跟随光标
您可以为 ManipulationDelta
事件使用 InvokeCommandAction 以避免破坏 MVVM 模式。 InvokeCommandAction
可以给viewmodel
传递一个参数,我们可以通过参数传递selecteditem
。 ManipulationDelta
的对象应该是按钮而不是 ItemsControl
并且 InvokeCommandAction
将起作用,您实际拖动的是按钮本身。更新代码如下:
XAML
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Name="root">
...
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button x:Name="PageItem" Background="Transparent" BorderBrush="DodgerBlue" Width="{Binding Width}" Height="{Binding Height}" ManipulationMode="TranslateX, TranslateY" IsHitTestVisible="{Binding IsChecked, ElementName=SelectToolButton, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" >
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="ManipulationDelta" SourceObject="{Binding ElementName=PageItem}">
<Core:InvokeCommandAction Command="{Binding DataContext.SendMyDC, ElementName=root}" CommandParameter="{Binding}"></Core:InvokeCommandAction>
<Core:CallMethodAction TargetObject="{Binding DataContext, ElementName=root, Mode=OneWay}" MethodName="PointerDrag" />
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
<Button.RenderTransform>
<CompositeTransform TranslateX="{Binding X}" TranslateY="{Binding Y}"/>
</Button.RenderTransform>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
我的视图模型
Public Class myviewmodel
...
Private m_sendCommand As IDelegateCommand
Public Property SendMyDC As IDelegateCommand
Get
Return m_sendCommand
End Get
Protected Set(value As IDelegateCommand)
m_sendCommand = value
End Set
End Property
Public Sub New()
Me.SendMyDC = New DelegateCommand(AddressOf ExecuteSendMyDC)
Dim newrect As New RectItem
newrect.Height = 100
newrect.Width = 150
newrect.X = 50
newrect.Y = 50
_myrectangles.Add(newrect)
End Sub
Dim selrecitem As RectItem
Public Sub PointerDrag(sender As Object, e As ManipulationDeltaRoutedEventArgs)
Dim dx_point = e.Delta.Translation.X
NotifyPropertyChanged()
Dim dy_point = e.Delta.Translation.Y
NotifyPropertyChanged()
'Dim rec = TryCast(e.OriginalSource, Button)
'Dim selrecitem = TryCast(rec.DataContext, RectItem)
If selrecitem IsNot Nothing Then
selrecitem.X += dx_point
selrecitem.Y += dy_point
End If
End Sub
Private Sub ExecuteSendMyDC(param As Object)
selrecitem = CType(param, RectItem)
End Sub
End Class
DelegateCommand class
Public Class DelegateCommand
Implements IDelegateCommand
Private _execute As Action(Of Object)
Private _canExecute As Func(Of Object, Boolean)
#Region "Constructors"
Public Sub New(execute As Action(Of Object), canExecute As Func(Of Object, Boolean))
Me._execute = execute
Me._canExecute = canExecute
End Sub
Public Sub New(execute As Action(Of Object))
Me._execute = execute
Me._canExecute = AddressOf Me.AlwaysCanExecute
End Sub
#End Region
#Region "IDelegateCommand"
Private Function AlwaysCanExecute(param As Object) As Boolean
Return True
End Function
Public Function CanExecute(parameter As Object) As Boolean Implements System.Windows.Input.ICommand.CanExecute
Return _canExecute(parameter)
End Function
Public Event CanExecuteChanged(sender As Object, e As EventArgs) Implements System.Windows.Input.ICommand.CanExecuteChanged
Public Sub Execute(parameter As Object) Implements System.Windows.Input.ICommand.Execute
_execute(parameter)
End Sub
Public Sub RaiseCanExecuteChanged() Implements IDelegateCommand.RaiseCanExecuteChanged
RaiseEvent CanExecuteChanged(Me, EventArgs.Empty)
End Sub
#End Region
End Class
Public Interface IDelegateCommand
Inherits ICommand
Sub RaiseCanExecuteChanged()
End Interface
DelegateCommand 是一个常用的 class 供您进一步调用其他命令。更多详情请参考Command binding inside DataTemplate.
目前正在创建我的 windows 10 应用程序,我正在尝试按照 mvvm 模式在 canvas 上移动一个矩形。下面的代码有效,但我通过在我的视图模型 PointerDragEvent 中使用 uielemnt 破坏了 mvvm。
Dim rec = TryCast(e.OriginalSource, Button)
Dim selrecitem = TryCast(rec.DataContext, RectItem)
问题
有没有非 hacky/proper 的方法可以做到这一点?
如何检索我单击的项目并将其传递给我的视图模型?
canvas 上的所有项目都将动态创建。
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App11"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity" xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
x:Class="App11.MainPage"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.DataContext>
<local:myviewmodel/>
</Grid.DataContext>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="8*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="11*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ItemsControl x:Name="itemsControl" Grid.Column="1" Grid.Row="1" ItemsSource="{Binding myrectangles, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="ManipulationDelta">
<Core:CallMethodAction TargetObject="{Binding Mode=OneWay}" MethodName="PointerDrag"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="White">
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button x:Name="PageItem" Background="Transparent" BorderBrush="DodgerBlue" Width="{Binding Width}" Height="{Binding Height}" ManipulationMode="TranslateX, TranslateY" IsHitTestVisible="{Binding IsChecked, ElementName=SelectToolButton, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Command="{Binding SendMyDC, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<Button.RenderTransform>
<CompositeTransform TranslateX="{Binding X}" TranslateY="{Binding Y}"/>
</Button.RenderTransform>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
视图模型
Public Class myviewmodel
Implements INotifyPropertyChanged
Private Sub NotifyPropertyChanged(Optional propertyName As String = "")
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private _myrectangles As New ObservableCollection(Of RectItem)
Public Property myrectangles As ObservableCollection(Of RectItem)
Get
Return _myrectangles
End Get
Set(value As ObservableCollection(Of RectItem))
_myrectangles = value
NotifyPropertyChanged()
End Set
End Property
Public Sub New()
Dim newrect As New RectItem
newrect.Height = 100
newrect.Width = 150
newrect.X = 50
newrect.Y = 50
_myrectangles.Add(newrect)
End Sub
Public Sub PointerDrag(sender As Object, e As ManipulationDeltaRoutedEventArgs)
Dim dx_point = e.Delta.Translation.X
NotifyPropertyChanged()
Dim dy_point = e.Delta.Translation.Y
NotifyPropertyChanged()
Dim rec = TryCast(e.OriginalSource, Button)
Dim selrecitem = TryCast(rec.DataContext, RectItem)
selrecitem.X += dx_point
selrecitem.Y += dy_point
End Sub
End Class
RectItemClass
Public Class RectItem
Implements INotifyPropertyChanged
Private Sub NotifyPropertyChanged(Optional propertyName As String = "")
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Public Property X As Double
Get
Return m_X
End Get
Set
m_X = Value
NotifyPropertyChanged()
End Set
End Property
Private m_X As Double
Public Property Y As Double
Get
Return m_Y
End Get
Set
m_Y = Value
NotifyPropertyChanged()
End Set
End Property
Private m_Y As Double
Public Property Width As Double
Get
Return m_Width
End Get
Set
m_Width = Value
NotifyPropertyChanged()
End Set
End Property
Private m_Width As Double
Public Property Height As Double
Get
Return m_Height
End Get
Set
m_Height = Value
NotifyPropertyChanged()
End Set
End Property
Private m_Height As Double
End Class
编辑 #1 我没有使用项目控件,而是使用 ListView/Listbox 并将所选项目绑定到我的 vewimodel 中的 属性。对于列表视图,在使项目呈现器与其呈现的项目和列表框对齐时存在一些问题,指针向上事件不会触发。
<ListView x:Name="itemsControl" Grid.Column="1" Grid.Row="1" ItemsSource="{Binding myrectangles, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" Background="#FFF2F2F2" SelectedItem="{Binding selectedrec, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="ManipulationDelta">
<Core:CallMethodAction TargetObject="{Binding Mode=OneWay}" MethodName="PointerDrag"/>
</Core:EventTriggerBehavior>
<Core:EventTriggerBehavior EventName="PointerPressed">
<Core:CallMethodAction TargetObject="{Binding Mode=OneWay}" MethodName="PointerPressed"/>
</Core:EventTriggerBehavior>
<!--<Core:EventTriggerBehavior EventName="PointerReleased">
<Core:CallMethodAction TargetObject="{Binding Mode=OneWay}" MethodName="Up"/>
</Core:EventTriggerBehavior>-->
</Interactivity:Interaction.Behaviors>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="White">
</Canvas>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<!--<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>-->
<ListView.ItemTemplate>
<DataTemplate>
<Rectangle x:Name="PageItem" Width="{Binding Width}" Height="{Binding Height}" Fill="Transparent" Stroke="DodgerBlue" ManipulationMode="TranslateX, TranslateY" IsHitTestVisible="{Binding IsChecked, ElementName=SelectToolButton, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" >
<Rectangle.RenderTransform>
<CompositeTransform TranslateX="{Binding X}" TranslateY="{Binding Y}"/>
</Rectangle.RenderTransform>
</Rectangle>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
已更新 ViewModel
Public _selectedrec As New RectItem
Public Property selectedrec As RectItem
Get
Return _selectedrec
End Get
Set(value As RectItem)
_selectedrec = value
NotifyPropertyChanged()
End Set
End Property
Public Sub PointerDrag(sender As Object, e As ManipulationDeltaRoutedEventArgs)
Dim dx_point = e.Delta.Translation.X
NotifyPropertyChanged()
Dim dy_point = e.Delta.Translation.Y
NotifyPropertyChanged()
selectedrec.X += dx_point
NotifyPropertyChanged()
selectedrec.Y += dy_point
NotifyPropertyChanged()
End Sub
问题示例
无 itemcontainerstyle - 尝试将对象捕捉拖动到 canvas
的 0,0 时MyHalfFix - 取消注释 ItemContainerStyle - 一切正常,我的目标是什么
在实际程序中实现时的整体问题
红色的Item是listviewitem presenter。它被正确绘制,但定位与绘制的矩形不对齐,它总是捕捉到 canvas 的点 0,0。我可以使它透明,但正如您在绘制矩形时也看到的那样,它没有正确跟随光标
您可以为 ManipulationDelta
事件使用 InvokeCommandAction 以避免破坏 MVVM 模式。 InvokeCommandAction
可以给viewmodel
传递一个参数,我们可以通过参数传递selecteditem
。 ManipulationDelta
的对象应该是按钮而不是 ItemsControl
并且 InvokeCommandAction
将起作用,您实际拖动的是按钮本身。更新代码如下:
XAML
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Name="root">
...
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button x:Name="PageItem" Background="Transparent" BorderBrush="DodgerBlue" Width="{Binding Width}" Height="{Binding Height}" ManipulationMode="TranslateX, TranslateY" IsHitTestVisible="{Binding IsChecked, ElementName=SelectToolButton, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" >
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="ManipulationDelta" SourceObject="{Binding ElementName=PageItem}">
<Core:InvokeCommandAction Command="{Binding DataContext.SendMyDC, ElementName=root}" CommandParameter="{Binding}"></Core:InvokeCommandAction>
<Core:CallMethodAction TargetObject="{Binding DataContext, ElementName=root, Mode=OneWay}" MethodName="PointerDrag" />
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
<Button.RenderTransform>
<CompositeTransform TranslateX="{Binding X}" TranslateY="{Binding Y}"/>
</Button.RenderTransform>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
我的视图模型
Public Class myviewmodel
...
Private m_sendCommand As IDelegateCommand
Public Property SendMyDC As IDelegateCommand
Get
Return m_sendCommand
End Get
Protected Set(value As IDelegateCommand)
m_sendCommand = value
End Set
End Property
Public Sub New()
Me.SendMyDC = New DelegateCommand(AddressOf ExecuteSendMyDC)
Dim newrect As New RectItem
newrect.Height = 100
newrect.Width = 150
newrect.X = 50
newrect.Y = 50
_myrectangles.Add(newrect)
End Sub
Dim selrecitem As RectItem
Public Sub PointerDrag(sender As Object, e As ManipulationDeltaRoutedEventArgs)
Dim dx_point = e.Delta.Translation.X
NotifyPropertyChanged()
Dim dy_point = e.Delta.Translation.Y
NotifyPropertyChanged()
'Dim rec = TryCast(e.OriginalSource, Button)
'Dim selrecitem = TryCast(rec.DataContext, RectItem)
If selrecitem IsNot Nothing Then
selrecitem.X += dx_point
selrecitem.Y += dy_point
End If
End Sub
Private Sub ExecuteSendMyDC(param As Object)
selrecitem = CType(param, RectItem)
End Sub
End Class
DelegateCommand class
Public Class DelegateCommand
Implements IDelegateCommand
Private _execute As Action(Of Object)
Private _canExecute As Func(Of Object, Boolean)
#Region "Constructors"
Public Sub New(execute As Action(Of Object), canExecute As Func(Of Object, Boolean))
Me._execute = execute
Me._canExecute = canExecute
End Sub
Public Sub New(execute As Action(Of Object))
Me._execute = execute
Me._canExecute = AddressOf Me.AlwaysCanExecute
End Sub
#End Region
#Region "IDelegateCommand"
Private Function AlwaysCanExecute(param As Object) As Boolean
Return True
End Function
Public Function CanExecute(parameter As Object) As Boolean Implements System.Windows.Input.ICommand.CanExecute
Return _canExecute(parameter)
End Function
Public Event CanExecuteChanged(sender As Object, e As EventArgs) Implements System.Windows.Input.ICommand.CanExecuteChanged
Public Sub Execute(parameter As Object) Implements System.Windows.Input.ICommand.Execute
_execute(parameter)
End Sub
Public Sub RaiseCanExecuteChanged() Implements IDelegateCommand.RaiseCanExecuteChanged
RaiseEvent CanExecuteChanged(Me, EventArgs.Empty)
End Sub
#End Region
End Class
Public Interface IDelegateCommand
Inherits ICommand
Sub RaiseCanExecuteChanged()
End Interface
DelegateCommand 是一个常用的 class 供您进一步调用其他命令。更多详情请参考Command binding inside DataTemplate.