2012-07-27 73 views
0

当前设置

我有一个代表安装程序文件和有关文件的一些属性的自定义类,应符合以下接口绑定对象列表定制的ItemTemplate到的ItemsControl在MVVM

public interface IInstallerObject 
{ 
    string FileName { get; set; } 
    string FileExtension { get; set; } 
    string Path { get; set; } 
    int Build { get; set; } 
    ProductType ProductType { get; set; } 
    Architecture ArchType { get; set; } 
    bool Configurable { get; set; } 
    int AverageInstallTime { get; set; } 
    bool IsSelected { get; set; } 
} 

ViewModel有一个名为AvailableInstallerObjectsReadOnlyObservableCollection<IInstallerObject>属性。

我的View有一个GroupBox包含ItemsControl它结合上述性质。

<GroupBox Header="Products"> 
     <ItemsControl ItemsSource="{Binding Path=AvailableInstallerObjects}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal"> 
         <CheckBox IsChecked="{Binding Path=IsSelected}" 
            VerticalAlignment="Center" Margin="5"/> 
         <TextBlock Text="{Binding Path=FileName}" Margin="5" /> 
        </StackPanel> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </GroupBox> 

的结合工作正常,但它不是用户友好的。显示100多个项目。

需要帮助这里

我希望能够使用的IInstallerObject我的珍藏,但有View具有以下ItemTemplate结构呈现出来。

<GroupBox Header="Products"> 
     <ItemsControl ItemsSource="{Binding Path=AvailableInstallerObjects}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal"> 
         <CheckBox IsChecked="{Binding Path=IsSelected}" 
            VerticalAlignment="Center" Margin="5"/> 
         <TextBlock Text="{Binding Path=ProductType}" Margin="5" /> 
         <ComboBox ItemsSource="{Binding Path=Build}" /> 
        </StackPanel> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </GroupBox> 

基本上,我希望能够以组由ProductType属性,显示可用产品的列表,以表示对IInstallerObject S中ProductType的可用Build属性值ComboBox

我可以在ViewModel中使用LINQ来提取分组,但我不知道如何绑定到我已经提取的分组。

我的研究也发现了使用CollectionViewSource的可能性,但我不确定如何将其应用于我当前的设置。

我很感谢你的帮助。我愿意学习,所以如果我忽略了一些明显的情况,请直接告诉我这些信息,我很乐意教育自己。

回答

0

如果Build应该是一个集合类型。

所以你的班级应该以这样的结构为例。

Public Class Customer 
Public Property FirstName as string 
Public Property LastName as string 
Public Property CustomerOrders as observableCollection(OF Orders) 
End Class 

这应该会给你预期的结果。主要项目演示者中的每个项目都将显示名字姓氏和绑定到该客户订单的组合框。 我知道这很简单,但应该这样做。

0

您只需在视图中声明CollectionViewSource并将其绑定到ObservableCollection即可。在这个对象中,你声明了一个或多个GroupDescriptions,它将源分成几个组。

将此源绑定到列表框,为组描述创建一个模板并完成。

一个例子可以在这里找到:WPF Sample Series – ListBox Grouping, Sorting, Subtotals and Collapsible Regions。关于CollectionViewSource的更多信息可以在这里找到:WPF’s CollectionViewSource

0

你的问题的描述使我相信你正在寻找某种类型的colapsing /展开/分组/树视图的东西。

XAML的树视图

<Window x:Class="WPFLab12.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:loc="clr-namespace:WPFLab12" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <GroupBox Header="Products"> 
     <TreeView ItemsSource="{Binding Path=ProductTypes}"> 
      <TreeView.Resources> 
       <HierarchicalDataTemplate 
        DataType="{x:Type loc:ProductType}" 
        ItemsSource="{Binding AvailableInstallerObjects}"> 
        <TextBlock Text="{Binding Description}" /> 
       </HierarchicalDataTemplate> 
       <HierarchicalDataTemplate DataType="{x:Type loc:InstallerObject}"> 
        <StackPanel Orientation="Horizontal"> 
         <CheckBox IsChecked="{Binding Path=IsSelected}" 
            VerticalAlignment="Center" Margin="5"/> 
         <TextBlock Text="{Binding Path=FileName}" Margin="5" /> 
        </StackPanel> 
       </HierarchicalDataTemplate> 
      </TreeView.Resources> 
     </TreeView> 
     </GroupBox> 
    </Grid> 
</Window> 

是什么呢?那么,它会根据找到的数据类型在树中建立一个控制层次结构。第一个HierarchicalDataTemplate处理如何显示每个类的数据以及它们在层次结构中的关系。第二个HierarchicalDataTemplate处理如何显示每个InstallerObject。背后

代码的主窗口:

public partial class MainWindow : Window 
{ 
    public ReadOnlyObservableCollection<ProductType> ProductTypes 
    { 
     get { return (ReadOnlyObservableCollection<ProductType>)GetValue(ProductTypesProperty); } 
     set { SetValue(ProductTypesProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for ProductTypes. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty ProductTypesProperty = 
     DependencyProperty.Register("ProductTypes", typeof(ReadOnlyObservableCollection<ProductType>), typeof(MainWindow), new UIPropertyMetadata(null)); 

    public MainWindow() 
    { 
     this.InitializeComponent(); 

     this.ProductTypes = new ReadOnlyObservableCollection<ProductType>(
      new ObservableCollection<ProductType>() 
      { 
       new ProductType() 
       { 
        Description = "Type A", 
        AvailableInstallerObjects = new ReadOnlyObservableCollection<InstallerObject>(
         new ObservableCollection<InstallerObject>() 
         { 
          new InstallerObject() { FileName = "A" }, 
          new InstallerObject() { FileName = "B" }, 
          new InstallerObject() { FileName = "C" }, 
         }) 
       }, 

       new ProductType() 
       { 
        Description = "Type B", 
        AvailableInstallerObjects = new ReadOnlyObservableCollection<InstallerObject>(
         new ObservableCollection<InstallerObject>() 
         { 
          new InstallerObject() { FileName = "A" }, 
          new InstallerObject() { FileName = "D" }, 
         }) 
       } 
      }); 

     this.DataContext = this; 
    } 
} 

这完全是欺骗,虽然 - 通常是MainWindow.cs不会作为DataContext的,并有所有这些东西。但是对于这个例子,我只是让它列出了ProductType s,并用InstallerObject实例填充了每个ProductType类。我用

类,注意我做了一些假设和修改你的类,以更好地适应这个视图模型:

public class InstallerObject 
{ 
    public string FileName { get; set; } 
    public string FileExtension { get; set; } 
    public string Path { get; set; } 
    public int Build { get; set; } 
    public bool Configurable { get; set; } 
    public int AverageInstallTime { get; set; } 
    public bool IsSelected { get; set; } 
} 

public class ProductType 
{ 
    public string Description { get; set; } 
    public ReadOnlyObservableCollection<InstallerObject> AvailableInstallerObjects 
    { 
     get; 
     set; 
    } 
    public override string ToString() 
    { 
     return this.Description; 
    } 
} 

所以,在MVVM,在我看来,你的当前InstallerObject类更是一个模型层层次的东西。您可能会考虑将其在ViewModel中转换为一组更易于在View中管理的集合类。 ViewModel中的想法是对事物进行建模,类似于它们将如何被观察和对话。将您的扁平列表InstallerObjects转换为分层数据的新集合,以便更容易地绑定到视图。

有关各种使用和自定义TreeView的方法的更多信息:http://www.codeproject.com/Articles/124644/Basic-Understanding-of-Tree-View-in-WPF

相关问题