UWP App Dynamic Pivot MVVM 总是创建视图模型的新实例
UWP App Dynamic Pivot MVVM always creating new instance of viewmodel
我的代码需要帮助。我正在尝试实现如下图所示的布局
到目前为止,我已经创建了一个 UWP Windows 10 应用程序,如下所示
我正在使用 Vb.net,但也欢迎使用 C#。尝试遵循 Mvvm 模式并且不使用额外的 mvvm 框架 - 只是 xaml 行为。
我的最终目标是能够双击一个页面,然后使用 header 绑定到页面名称来创建一个新选项卡。出于测试目的,我添加了一个添加页面和添加选项卡按钮,因为双击无法正常工作。每次将新项目添加到选项卡的 collection 时,它都不会反映在 ui 中,因为数据模板正在创建我的视图模型的新实例,这是我不想要的即将发生。临时添加按钮调用正确的方法并执行我想通过双击实现的功能。 Ill post 下面是我的代码的最短示例。
<StackPanel Orientation="Horizontal" Grid.Column="1" Grid.Row="1">
<Button Width="200" VerticalAlignment="Stretch" Content="Add Page" Foreground="White">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Click">
<Core:CallMethodAction MethodName="AddPage" TargetObject="{Binding Mode=OneWay}"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
<Button Width="200" VerticalAlignment="Stretch" Content="Add Tab" Foreground="White">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Click">
<Core:CallMethodAction MethodName="AddSection" TargetObject="{Binding Mode=OneWay}"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
</StackPanel>
<Pivot Grid.Column="1" Grid.Row="2" Foreground="White" ItemsSource="{Binding PivotItems, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" Foreground="White"/>
</DataTemplate>
</Pivot.HeaderTemplate>
<Pivot.ItemTemplate>
<DataTemplate>
<GridView ItemsSource="{Binding Result, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="DoubleTapped">
<Core:CallMethodAction MethodName="AddSection"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
<GridView.ItemTemplate>
<DataTemplate>
<Grid x:Name="CanvasControl" Background="#00000000" Width="200" Height="200" >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="8*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="11*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Canvas Grid.Column="1" Grid.Row="1" Margin="10" Background="White" DoubleTapped="Canvas_DoubleTapped" />
<TextBox Grid.Column="1" Grid.Row="2" Foreground="White" FontSize="14" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" Padding="0" Background="{x:Null}" BorderBrush="{x:Null}" Text="{Binding CanvasCollection[0].CanvasName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Grid.Column="1" Grid.Row="0" Foreground="White" FontSize="12" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="10" IsHitTestVisible="False" Text="{Binding CanvasCollection[0].CanvasMaster}" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</DataTemplate>
</Pivot.ItemTemplate>
</Pivot>
</Grid>
视图模型
Public Class ProjectDataViewModel
Implements INotifyPropertyChanged
Private WindowData As New CanvasData
Private randomdata As New DataGenerators
Private m_PivotItems As New ObservableCollection(Of PivotSection)
Private Canvas_Collection As New ObservableCollection(Of CanvasData)
Private mycollection As New CanvasData
Private pivotItem_Home As New PivotSection() With {.Name = "Home"}
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 PropertyCollectionItemName As String
Get
Return WindowData.CanvasName
End Get
Set(value As String)
WindowData.CanvasName = value
End Set
End Property
Public Property PropertyCollectionItemMaster As String
Get
Return WindowData.CanvasMaster
End Get
Set(value As String)
WindowData.CanvasMaster = value
End Set
End Property
Public Property CanvasCollection As ObservableCollection(Of CanvasData)
Get
Return Canvas_Collection
End Get
Private Set(value As ObservableCollection(Of CanvasData))
Canvas_Collection = value
NotifyPropertyChanged()
End Set
End Property
Public Property my_collection As CanvasData
Get
Return mycollection
End Get
Set(value As CanvasData)
mycollection = value
NotifyPropertyChanged()
End Set
End Property
Public Property PivotItems() As ObservableCollection(Of PivotSection)
Get
Return m_PivotItems
End Get
Set
m_PivotItems = Value
NotifyPropertyChanged()
End Set
End Property
Public Sub AddSection()
Dim pivotItem_New As New PivotSection() With {.Name = "Item Header " + PivotItems.Count.ToString}
m_PivotItems.Add(pivotItem_New)
End Sub
Public Sub AddPage()
Dim Newpage As New PivotItemContent
Newpage.CanvasCollection.Add(New CanvasData With {.CanvasName = "Page " + pivotItem_Home.Result.Count.ToString, .CanvasMaster = "Master "})
pivotItem_Home.Result.Add(newpage)
End Sub
Sub New()
Dim indexPage As New PivotItemContent
PivotItems = New ObservableCollection(Of PivotSection)
PivotItems.Add(pivotItem_Home)
indexPage.CanvasCollection.Add(New CanvasData With {.CanvasName = "Home", .CanvasMaster = "Master"})
pivotItem_Home.Result.Add(indexPage)
End Sub
透视节Class
End Class
Public Class PivotSection
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 Name() As String
Get
Return m_Name
End Get
Set
m_Name = Value
End Set
End Property
Private m_Name As String
Public Property SystemLabel() As String
Get
Return m_SystemLabel
End Get
Set
m_SystemLabel = Value
End Set
End Property
Private m_SystemLabel As String
Public Property Result() As ObservableCollection(Of PivotItemContent)
Get
Return m_Result
End Get
Set
m_Result = Value
NotifyPropertyChanged()
End Set
End Property
Private m_Result As New ObservableCollection(Of PivotItemContent)
'Public Sub New()
' Result = New ObservableCollection(Of PivotGroup)
'End Sub
End Class
PivotContent Class
Public Class PivotItemContent
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 Canvas_Collection As New ObservableCollection(Of CanvasData)
Public Property CanvasCollection As ObservableCollection(Of CanvasData)
Get
Return Canvas_Collection
End Get
Private Set(value As ObservableCollection(Of CanvasData))
Canvas_Collection = value
NotifyPropertyChanged()
End Set
End Property
Private Page_Name As String
Public Property PageName As String
Get
Return Page_Name
End Get
Set(value As String)
Page_Name = value
NotifyPropertyChanged()
End Set
End Property
Private Page_Master As String
Public Property PageMaster As String
Get
Return Page_Master
End Get
Set(value As String)
Page_Master = value
NotifyPropertyChanged()
End Set
End Property
End Class
CavasDataclass
Imports Windows.UI
Public Class CanvasData
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(Optional propertyName As String = "")
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
Private _CanvasMaster_Name As String
Private _CanvasName As String
Public Property CanvasMaster() As String
Get
Return _CanvasMaster_Name
End Get
Set(ByVal value As String)
_CanvasMaster_Name = value
NotifyPropertyChanged()
End Set
End Property
Public Property CanvasName As String
Get
Return _CanvasName
End Get
Set(value As String)
_CanvasName = value
NotifyPropertyChanged()
End Set
End Property
End Class
在这种情况下,您可以拥有一个 TabList
页面,其中将包含 GridView
以及所有打开的选项卡。每个项目都将使用 ItemTemplate
,您可以在其中添加关闭按钮和预览。
要启用打开标签页,可以将GridView
的IsItemClickEnabled
属性设置为true
,然后处理ItemClick
事件就知道了用户点击了哪个选项卡。然后,您可以使用此信息导航到您创建的 TabDetail
页面。
创建新选项卡也很简单 - 只需将新项目添加到 GridView
并直接导航到它。
我的代码需要帮助。我正在尝试实现如下图所示的布局
到目前为止,我已经创建了一个 UWP Windows 10 应用程序,如下所示
我正在使用 Vb.net,但也欢迎使用 C#。尝试遵循 Mvvm 模式并且不使用额外的 mvvm 框架 - 只是 xaml 行为。
我的最终目标是能够双击一个页面,然后使用 header 绑定到页面名称来创建一个新选项卡。出于测试目的,我添加了一个添加页面和添加选项卡按钮,因为双击无法正常工作。每次将新项目添加到选项卡的 collection 时,它都不会反映在 ui 中,因为数据模板正在创建我的视图模型的新实例,这是我不想要的即将发生。临时添加按钮调用正确的方法并执行我想通过双击实现的功能。 Ill post 下面是我的代码的最短示例。
<StackPanel Orientation="Horizontal" Grid.Column="1" Grid.Row="1">
<Button Width="200" VerticalAlignment="Stretch" Content="Add Page" Foreground="White">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Click">
<Core:CallMethodAction MethodName="AddPage" TargetObject="{Binding Mode=OneWay}"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
<Button Width="200" VerticalAlignment="Stretch" Content="Add Tab" Foreground="White">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Click">
<Core:CallMethodAction MethodName="AddSection" TargetObject="{Binding Mode=OneWay}"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
</StackPanel>
<Pivot Grid.Column="1" Grid.Row="2" Foreground="White" ItemsSource="{Binding PivotItems, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" Foreground="White"/>
</DataTemplate>
</Pivot.HeaderTemplate>
<Pivot.ItemTemplate>
<DataTemplate>
<GridView ItemsSource="{Binding Result, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="DoubleTapped">
<Core:CallMethodAction MethodName="AddSection"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
<GridView.ItemTemplate>
<DataTemplate>
<Grid x:Name="CanvasControl" Background="#00000000" Width="200" Height="200" >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="8*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="11*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Canvas Grid.Column="1" Grid.Row="1" Margin="10" Background="White" DoubleTapped="Canvas_DoubleTapped" />
<TextBox Grid.Column="1" Grid.Row="2" Foreground="White" FontSize="14" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" Padding="0" Background="{x:Null}" BorderBrush="{x:Null}" Text="{Binding CanvasCollection[0].CanvasName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Grid.Column="1" Grid.Row="0" Foreground="White" FontSize="12" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="10" IsHitTestVisible="False" Text="{Binding CanvasCollection[0].CanvasMaster}" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</DataTemplate>
</Pivot.ItemTemplate>
</Pivot>
</Grid>
视图模型
Public Class ProjectDataViewModel
Implements INotifyPropertyChanged
Private WindowData As New CanvasData
Private randomdata As New DataGenerators
Private m_PivotItems As New ObservableCollection(Of PivotSection)
Private Canvas_Collection As New ObservableCollection(Of CanvasData)
Private mycollection As New CanvasData
Private pivotItem_Home As New PivotSection() With {.Name = "Home"}
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 PropertyCollectionItemName As String
Get
Return WindowData.CanvasName
End Get
Set(value As String)
WindowData.CanvasName = value
End Set
End Property
Public Property PropertyCollectionItemMaster As String
Get
Return WindowData.CanvasMaster
End Get
Set(value As String)
WindowData.CanvasMaster = value
End Set
End Property
Public Property CanvasCollection As ObservableCollection(Of CanvasData)
Get
Return Canvas_Collection
End Get
Private Set(value As ObservableCollection(Of CanvasData))
Canvas_Collection = value
NotifyPropertyChanged()
End Set
End Property
Public Property my_collection As CanvasData
Get
Return mycollection
End Get
Set(value As CanvasData)
mycollection = value
NotifyPropertyChanged()
End Set
End Property
Public Property PivotItems() As ObservableCollection(Of PivotSection)
Get
Return m_PivotItems
End Get
Set
m_PivotItems = Value
NotifyPropertyChanged()
End Set
End Property
Public Sub AddSection()
Dim pivotItem_New As New PivotSection() With {.Name = "Item Header " + PivotItems.Count.ToString}
m_PivotItems.Add(pivotItem_New)
End Sub
Public Sub AddPage()
Dim Newpage As New PivotItemContent
Newpage.CanvasCollection.Add(New CanvasData With {.CanvasName = "Page " + pivotItem_Home.Result.Count.ToString, .CanvasMaster = "Master "})
pivotItem_Home.Result.Add(newpage)
End Sub
Sub New()
Dim indexPage As New PivotItemContent
PivotItems = New ObservableCollection(Of PivotSection)
PivotItems.Add(pivotItem_Home)
indexPage.CanvasCollection.Add(New CanvasData With {.CanvasName = "Home", .CanvasMaster = "Master"})
pivotItem_Home.Result.Add(indexPage)
End Sub
透视节Class
End Class
Public Class PivotSection
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 Name() As String
Get
Return m_Name
End Get
Set
m_Name = Value
End Set
End Property
Private m_Name As String
Public Property SystemLabel() As String
Get
Return m_SystemLabel
End Get
Set
m_SystemLabel = Value
End Set
End Property
Private m_SystemLabel As String
Public Property Result() As ObservableCollection(Of PivotItemContent)
Get
Return m_Result
End Get
Set
m_Result = Value
NotifyPropertyChanged()
End Set
End Property
Private m_Result As New ObservableCollection(Of PivotItemContent)
'Public Sub New()
' Result = New ObservableCollection(Of PivotGroup)
'End Sub
End Class
PivotContent Class
Public Class PivotItemContent
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 Canvas_Collection As New ObservableCollection(Of CanvasData)
Public Property CanvasCollection As ObservableCollection(Of CanvasData)
Get
Return Canvas_Collection
End Get
Private Set(value As ObservableCollection(Of CanvasData))
Canvas_Collection = value
NotifyPropertyChanged()
End Set
End Property
Private Page_Name As String
Public Property PageName As String
Get
Return Page_Name
End Get
Set(value As String)
Page_Name = value
NotifyPropertyChanged()
End Set
End Property
Private Page_Master As String
Public Property PageMaster As String
Get
Return Page_Master
End Get
Set(value As String)
Page_Master = value
NotifyPropertyChanged()
End Set
End Property
End Class
CavasDataclass
Imports Windows.UI
Public Class CanvasData
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(Optional propertyName As String = "")
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
Private _CanvasMaster_Name As String
Private _CanvasName As String
Public Property CanvasMaster() As String
Get
Return _CanvasMaster_Name
End Get
Set(ByVal value As String)
_CanvasMaster_Name = value
NotifyPropertyChanged()
End Set
End Property
Public Property CanvasName As String
Get
Return _CanvasName
End Get
Set(value As String)
_CanvasName = value
NotifyPropertyChanged()
End Set
End Property
End Class
在这种情况下,您可以拥有一个 TabList
页面,其中将包含 GridView
以及所有打开的选项卡。每个项目都将使用 ItemTemplate
,您可以在其中添加关闭按钮和预览。
要启用打开标签页,可以将GridView
的IsItemClickEnabled
属性设置为true
,然后处理ItemClick
事件就知道了用户点击了哪个选项卡。然后,您可以使用此信息导航到您创建的 TabDetail
页面。
创建新选项卡也很简单 - 只需将新项目添加到 GridView
并直接导航到它。