繁体   English   中英

将对象绑定到wpf控件中

[英]binding an object into a control of wpf

我是WPF的新手,我想就如何将此对象绑定到wpf控件提供快速建议,但我不知道应该使用哪个控件:

public class Parent
{
  public string Name{get; set;}
  public List<Child> Childs {get; set;}
}

public class Child
{
  public string Name{get; set;}
  public int Age {get; set;}
}

public class ParentFactory
{
   public List<Parent> Parents {get; set;}

   public ParentFactory()
   {
      Child child1 = new Child() {Name="Peter", Age=10;};
      Child child2 = new Child() {Name="Mary", Age=9;};
      Child child3 = new Child() {Name="Becky", Age=12;};

      Parent parent1 = new Parent(){Name="Adam", Childs = new List<Child<>(){child1, child2}};
      Parent parent2 = new Parent(){Name="Kevin", Childs = new List<Child<>(){child3}};

      Parents = new List<Parent>(){parent1, parent2};
   }
}

创建此实例后:

ParentFactory parentFactory = new ParentFactory();

我想将parentFactory.Parents()绑定到WPF中的控件。 我希望看到这样的东西:


亚当

-彼得,10岁

-9岁的玛丽

凯文

-贝基(12岁)


它们都显示在文本框中,我可以更改它们。

提前致谢。

将TreeView与HierarchicalDataTemplate一起使用。

但是请注意,如果没有在模型上实现INotifyPropertyChanged,绑定将不会在任何属性更改时更新。 另外,如果不使用ObservableCollections替换列表,则在向列表中添加更多项时,视图不会更新。

这样的事情应该起作用,首先定义您的模板:

<Window.Resources>
    <HierarchicalDataTemplate DataType="{x:Type local:Parent}" ItemsSource="{Binding Childs}">
        <TextBlock Text="{Binding Name}"/>
    </HierarchicalDataTemplate>
    <DataTemplate DataType="{x:Type local:Child}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Name}"/>
            <TextBlock>, </TextBlock>
            <TextBlock Text="{Binding Age}"/>
        </StackPanel>
    </DataTemplate>
</Window.Resources>

然后,您可以将它们与这样的TreeView一起使用(假设Parents是TreeView的DataContext中的一个属性):

<TreeView ItemsSource="{Binding Parents}"/>

如果您不希望使用TreeView,则可以使用ListView轻松地将其列出来,将DataTemplates更改为此:

    <DataTemplate DataType="{x:Type local:Parent}">
        <StackPanel>
            <TextBlock Text="{Binding Name}"/>
            <ListView ItemsSource="{Binding Childs}"/>
        </StackPanel>
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:Child}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Name}"/>
            <TextBlock>, </TextBlock>
            <TextBlock Text="{Binding Age}"/>
        </StackPanel>
    </DataTemplate>

然后可以像这样绑定它:

<ListView ItemsSource="{Binding Parents}"/>

注意:您可能想稍微弄些样式,因为开箱即用,看起来有点废话。 您可能至少要缩进子级ListView(在父级DataTemplate中定义的子级)并摆脱其边界。

另请注意:用于布局名称和年龄的多个TextBlock的StackPanel也不理想,但它又快又脏。 您可能想以不同的方式处理。 您可以使用(多)转换器对其进行格式化,使用StringFormat或将其他属性添加到模型中以供显示,甚至可以覆盖子类上的ToString。

另一个编辑

一个使用DataGrid的快速(丑陋)示例:

<DataGrid ItemsSource="{Binding Parents}" AutoGenerateColumns="False">
    <DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <DataGrid ItemsSource="{Binding Childs}"/>
        </DataTemplate>
    </DataGrid.RowDetailsTemplate>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Name}"/>
    </DataGrid.Columns>
</DataGrid>

这将使用行详细信息模板将数据网格放入数据网格中。 如果单击一行,它将显示子项作为行详细信息。 如果希望详细信息始终可用,则可以删除RowDetailsTemplate并将DataGridTextColumn替换为DataGridTemplateColumn,然后为您的数据定义一个模板。

如果您不希望使用树状视图(这可能是最好的选择,因为它具有层次结构-尽管它只是一个一级的深度,所以您可能仍然需要列表)。
您可以做这样的事情(这是一个粗略的轮廓,您应该填写点)...

<ItemsControl ItemsSource="{Binding AllNodes}">
</ItemsControl>

...并为每种类型专门定义了模板,就像Matt所说的...

<DataTemplate DataType="{x:Type namespace:Child}">
...
</DataTemplate>

<DataTemplate DataType="{x:Type namespace:Parent}">
...
</DataTemplate>

...虽然AllNodes是您需要从现有层次结构中flatten的列表,但是您可以使用它...

var allnodes = Parents.SelectMany(p => new object[]{p}.Concat(p.Childs));  

...并将AllNodes公开为类似于Parents的属性-您只需要按照建议的方式正确实现INotifyPropertyChanged的View模型。

希望这可以帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM