【发布时间】:2017-02-23 22:35:48
【问题描述】:
目前正在创建我的 windows 10 应用程序,我正在尝试按照 mvvm 模式在画布上移动一个矩形。下面的代码有效,但我通过在我的视图模型 PointerDragEvent 中使用 uielemnt 破坏了 mvvm。
Dim rec = TryCast(e.OriginalSource, Button)
Dim selrecitem = TryCast(rec.DataContext, RectItem)
问题
是否有一种非 hacky/正确的方式来做到这一点?
如何检索我单击的项目并将其传递给我的视图模型?
画布上的所有项目都将动态创建。
<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
矩形项目类
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 时,让 item Presenter 与它所展示的 item 对齐存在一些问题,并且与 listbox 对齐,指针向上事件不会触发。
<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>
更新的视图模型
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 - 尝试将对象拖动到画布的 0,0 时
MyHalfFix - 取消注释 ItemContainerStyle - 一切正常,我的目标是
在实际程序中实现时的总体问题
红色的Item是listviewitem Presenter。它被正确绘制,但定位与绘制的矩形不对齐,它总是捕捉到画布的 0,0 点。我可以让它透明,但你也可以在绘制矩形时看到它没有正确跟随光标
【问题讨论】:
标签: vb.net xaml mvvm uwp windows-10-universal