因此,我目前正在使用 WPF 和 MVVM,并且一直在嘗試找到一種方法來選擇串列中的專案并將其顯示在新視窗中。我想出了一個我個人喜歡的解決方案,但我不確定它是否遵循有效的 MVVM 架構。
所以我有我的MainWindow.xaml
<Window x:Class="Views.MainWindow"
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:local="clr-namespace:Views"
xmlns:viewmodel="clr-namespace:Views.MVVM.ViewModel"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
Background="#252525">
<Window.DataContext>
<viewmodel:MainViewModel/>
</Window.DataContext>
<StackPanel Orientation="Horizontal">
<ListView ItemsSource="{Binding NetworkObjects}"
Style="{StaticResource ListStyle}"
Name="MainList"/>
</StackPanel>
</Window>
它使用這種樣式來系結集合中的每個專案,并且還應用MouseBinding允許我LeftDoubleClick呼叫命令的專案。我將整個物件作為命令引數傳遞,因為那是DataContext. 這是新視窗所需要的。
<Style TargetType="ListView" x:Key="ListStyle">
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<DockPanel Margin="2">
<DockPanel.InputBindings>
<MouseBinding Gesture="LeftDoubleClick"
Command="{Binding DisplayItemCommand}"
CommandParameter="{Binding Path=.}"/>
</DockPanel.InputBindings>
<DockPanel.Style>
<Style TargetType="DockPanel">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#303030"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="Transparent"/>
</Trigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ListBoxItem}},
Path=IsSelected}" Value="True">
<Setter Property="Background" Value="MediumSpringGreen"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DockPanel.Style>
<TextBlock Text="{Binding NetworkModel.Address}" Foreground="Black"/>
</DockPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
The MainViewModel does nothing but generate some dummy data in the constructor. This is where I start doubting whether or not this is valid MVVM, because I'm generating objects that are not based on a Model but rather an entire ViewModel which in theory makes sense, but I'm not sure.
public ObservableCollection<NetworkObjectViewModel> NetworkObjects { get; set; }
public MainViewModel()
{
NetworkObjects = new ObservableCollection<NetworkObjectViewModel>();
for (int i = 0; i < 10; i )
{
NetworkObjects.Add(new NetworkObjectViewModel() { NetworkModel = new NetworkModel { Address = $"Address {i}", Port = i } });
}
}
And the NetworkObjectViewModel contains a RelayCommand and NetworkModel.
public class NetworkObjectViewModel
{
public NetworkModel NetworkModel { get; set; }
public RelayCommand DisplayItemCommand { get; set; }
public NetworkObjectViewModel()
{
DisplayItemCommand = new RelayCommand(o =>
{
WindowService.ShowWindow(o);
});
}
}
The WindowService is simple, it just creates a new GenericWindow and sets it DataContext so that it can make a decision and display the correct UserControl based on the DataContext
internal class WindowService
{
public static void ShowWindow(object DataCtx)
{
var t = new GenericWindow();
t.DataContext = DataCtx;
t.Show();
}
}
And here's the GenericWindow.xaml
<Window.Resources>
<DataTemplate DataType="{x:Type vms:NetworkObjectViewModel}">
<v:TestView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vms:NetworkObjectViewModel2}">
<v:TestView2/>
</DataTemplate>
</Window.Resources>
<ContentPresenter Content="{Binding .}" />
And the TestView.xaml which is nothing but a simple UserControl that looks like this
<Grid>
<TextBox Text="{Binding NetworkModel.Address, UpdateSourceTrigger=PropertyChanged}"
Width="100"
Height="25"
IsEnabled="True"/>
</Grid>
uj5u.com熱心網友回復:
這是我開始懷疑這是否是有效的 MVVM 的地方,因為我生成的物件不是基于模型而是基于整個 ViewModel,這在理論上是有意義的,但我不確定。
這很有意義。
MVVM 中的模型通常指的是您不想直接系結到的型別,例如資料傳輸物件 (DTO)、包含業務邏輯甚至服務或存盤庫的域物件。
創建和公開一組“子”視圖模型以從“父”視圖模型類系結到是一種非常好的和常見的方法。
uj5u.com熱心網友回復:
我在這里有一個可能有意義的建議:將 DisplayItemCommand 移動到 MainViewModel。Xaml 中的系結應調整為:
<MouseBinding Gesture="LeftDoubleClick"
Command="{Binding DataContext.DisplayItemCommand ,RelativeSource={RelativeSource AncestorType={x:Type Window},Mode=FindAncestor}}"
CommandParameter="{Binding DataContext,RelativeSource={RelativeSource AncestorType={x:Type ListViewItem},Mode=FindAncestor}}"/>
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/425996.html
上一篇:重做和撤消筆劃的順序錯誤?
