我可以使用哪些技术从使用WPF的对象集合创建一系列UI元素?

时间:2010-03-25 17:03:45

标签: wpf

我是WPF的新手,在我以完全错误的方式解决问题之前,我想知道WPF是否足够聪明,可以为我处理一些事情。

想象一下,我有一个包含对象的集合。每个对象具有相同的已知类型并具有两个参数。名称(字符串)和Picked(布尔值)。

将在运行时填充该集合。

我想在运行时构建一个UI元素,将该集合表示为一系列复选框。如果用户更改了复选框的选定状态,我希望更新集合中任何给定对象的Picked参数。

对我来说,答案很简单。我遍历集合并为每个对象创建一个新的复选框,动态连接一个ValueChanged事件以捕获应该更改Picked。

然而,我发现,我可能能够利用WPF的一些未知功能来更好地(或“正确地”)做到这一点。例如,这里可以使用数据绑定吗?

我对任何人的想法都很感兴趣。

谢谢,

电子

FootNote:集合的结构可以完全改变,以更好地适应任何选择的解决方案,但最终我将始终从一些字符串和布尔对列表开始,并以此结束。

3 个答案:

答案 0 :(得分:1)

您可以使用数据模板。这是关于它的good post

答案 1 :(得分:1)

这正是WPF简化的场景。事件处理程序 - 哇!数据绑定和数据模板使这一点变得简单。我已经构建了一个示例来说明如何执行此操作。

这是代码隐藏,它声明了一个代表你的项目的类 - PickedItem。然后我创建了这些项目的集合,并用一些样本填充它。

public partial class DataBoundCollection : Window
{
    public DataBoundCollection()
    {
        Items = new ObservableCollection<PickedItem>();
        Items.Add(new PickedItem("Item 1"));
        Items.Add(new PickedItem("Item 2"));
        Items.Add(new PickedItem("Item 3"));

        InitializeComponent();
    }

    public ObservableCollection<PickedItem> Items
    {
        get;
        set;
    }
}

public class PickedItem
{
    public PickedItem(string name)
    {
        Name = name;
        Picked = false;
    }

    public string Name
    {
        get;
        set;
    }

    public bool Picked
    {
        get;
        set;
    }
}

现在,让我们看看这个窗口的XAML标记:

<Window x:Class="TestWpfApplication.DataBoundCollection"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataBoundCollection" Height="300" Width="300"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
    <ListBox ItemsSource="{Binding Items}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <CheckBox IsChecked="{Binding Picked}" Margin="5"/>
                    <TextBlock Text="{Binding Name}" VerticalAlignment="Center"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

我创建一个ListBox来保存项目,并将其ItemsSource属性绑定到我在代码隐藏中创建的集合。然后,我为ListBox提供ItemTemplate,确定每个PickedItem的呈现方式。在这种情况下,DataTemplate就像复选框和一些文本一样简单,两者都绑定到PickedItem上的成员变量。现在,当我检查这些项目中的任何一项时,底层集合中的数据将被实时修改,不需要事件处理程序。当当!

alt text http://img405.imageshack.us/img405/1083/databoundcollection.png

答案 2 :(得分:1)

我强烈推荐ItemsControl,它的行为尽可能接近ASP.Net转发器控件,因此非常灵活。

将项目控件声明为:

        <ItemsControl Name="YourItemsControl" 
                      ItemsSource="{Binding Path=YourCollection}" 
                      ItemTemplate="{StaticResource YourTemplate}">
        </ItemsControl>   

然后您可以使用datatemplate将数据组织成用户的显示格式

    <DataTemplate x:Key="ProjectsTemplate">

        <StackPanel Margin="0,0,0,10">
            <Border CornerRadius="2,2,0,0" Background="{StaticResource ItemGradient}" d:LayoutOverrides="Width, Height">
                <local:ItemContentsUserControl Height="30"/>
            </Border>
     ...

有用的ItemsControl链接

我希望这会对你有所帮助。