gpt4 book ai didi

c# - 使用 MVVM 模式的 UI 设计

转载 作者:太空狗 更新时间:2023-10-29 23:34:30 25 4
gpt4 key购买 nike

我正在尝试选择以 MVVM 方式实现此 UI 的最佳方式。我是 WPF 的新手(大约 2 个月),但我有丰富的 WinForms 经验。 enter image description here

这里的 ListBox 就像一个 TabControl(因此它将 View 切换到右侧),并且基本上包含表格中显示的项目类型。所有 UI 都是动态的(ListBox 项、TabItems 和 Columns 是在运行时确定的)。该应用程序以 WPF 和 Silverlight 为目标。

ViewModel 需要的类:

public abstract class ViewModel : INotifyPropertyChanged {}
public abstract class ContainerViewModel : ViewModel
{
public IList<ViewModel> Workspaces {get;set;}
public ViewModel ActiveWorkspace {get;set;}
}
public class ListViewModel<TItem> where TItem : class
{
public IList<TItem> ItemList { get; set; }
public TItem ActiveItem { get; set; }
public IList<TItem> SelectedItems { get; set; }
}
public class TableViewModel<TItem> : ListViewModel<TItem> where TItem : class
{
public Ilist<ColumnDescription> ColumnList { get; set; }
}

现在的问题是如何将它连接到 View。

我在这里可以看到 2 种基本方法:

  • 使用 XAML:由于 XAML 中缺乏泛型支持,我将失去强类型。
  • 没有 XAML:我可以重用相同的 ListView<T> : UserControl.

接下来,如何连接数据,我在这里看到了 3 种方法(这里使用或不使用 XAML 无关紧要)。由于没有简单的数据绑定(bind)到 DataGrid 的列或 TabControl 的 TabItems,我看到的方法是:

  • 将 DataBinding 与 IValueConverter 结合使用:我认为这不适用于 WPF|Silverlight 开箱即用控件,因为我需要的某些属性是只读的或无法以双工方式绑定(bind)。 (对此我不确定,但我觉得这行不通)。
  • 通过在 View 中订阅 INotifyPropertyChanged 使用手动逻辑:ViewModel.PropertyChanged+= ....ViewModel.ColumnList.CollectionChanged+= ....

  • 使用支持此绑定(bind)的自定义控件:自己编写代码或查找支持此绑定(bind)的 3d 方控件(我不喜欢此选项,我的 WPF 技能太低无法自己编写代码,我怀疑我会找到免费控件)


更新:2011 年 2 月 28 日事情变得越来越糟,我决定使用 TreeView 而不是 ListBox,这是一场噩梦。您可能猜到 TreeView.SelectedItems 是只读属性,因此没有数据绑定(bind)。嗯,好吧,让我们用老方法来做,订阅事件以将 View 与 View 模型同步。在这一点上,突然发现 DisplayMemberPath 对 TreeView 没有任何作用(嗯,好吧,让我们用旧方法 ToString() )。然后在 View 的方法中,我尝试将 ViewModel.SelectedItem 与 TreeView 同步:

private void UpdateTreeViewSelectedItem()
{
//uiCategorySelector.SelectedItem = ReadOnly....

//((TreeViewItem) uiCategorySelector.Items[uiCategorySelector.Items.IndexOf(Model.ActiveCategory)]).IsSelected = true;
// Will not work Items's are not TreeViewItem but Category object......

//((TreeViewItem) uiCategorySelector.ItemContainerGenerator.ContainerFromItem(Model.ActiveCategory)).IsSelected = true;
//Doesn't work too.... NULL // Changind DataContext=Model and Model = new MainViewModel line order doesn't matter.
//Allright.. figure this out later...
}

而且我能想到的方法都行不通....

这里是我的示例项目的链接,该示例项目使用 MVVM 演示了 Control Library Hell:http://cid-b73623db14413608.office.live.com/self.aspx/.Public/MVVMDemo.zip

最佳答案

Maciek 的回答实际上比需要的更复杂。您根本不需要模板选择器。创建异构选项卡控件:

  1. 为您希望显示为选项卡项的每种类型的 View 创建一个 View 模型类。确保每个类都实现一个 Text 属性,其中包含您希望在其项目的选项卡中显示的文本。

  2. 为每个 View 模型类创建一个 DataTemplateDataType 设置为类的类型,并将模板放入资源字典中。

  3. 使用 View 模型的实例填充集合。

  4. 创建一个 TabControl 并将其 ItemsSource 绑定(bind)到此集合,并添加一个显示每个项目的 ItemTemplate 属性的 Text

这是一个不使用 View 模型的示例(并且它也没有实现 Text 属性,因为我绑定(bind)的对象是简单的 CLR 类型),但展示了模板选择在此上下文中的工作方式:

<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:coll="clr-namespace:System.Collections;assembly=mscorlib">
<DockPanel>
<DockPanel.Resources>
<coll:ArrayList x:Key="Data">
<sys:String>This is a string.</sys:String>
<sys:Int32>12345</sys:Int32>
<sys:Decimal>23456.78</sys:Decimal>
</coll:ArrayList>
<DataTemplate DataType="{x:Type sys:String}">
<TextBlock Text="{Binding}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type sys:Int32}">
<StackPanel Orientation="Horizontal">
<TextBlock>This is an Int32:</TextBlock>
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type sys:Decimal}">
<StackPanel Orientation="Horizontal">
<TextBlock>This is a Decimal: </TextBlock>
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</DockPanel.Resources>
<TabControl ItemsSource="{StaticResource Data}">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
</DockPanel>
</Page>

当然,在真正的 MVVM 应用程序中,那些 DataTemplate 会使用 UserControl 将每种类型映射到它的 View :

<DataTemplate DataType="{x:Type my:ViewModel}">
<my:View DataContext="{Binding}"/>
</DataTemplate>

关于c# - 使用 MVVM 模式的 UI 设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5133513/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com