开发者

What techniques can I employ to create a series of UI Elements from a collection of objects using WPF?

I'm new to WPF and before I dive in solving a problem in completely the wrong way I was wondering if WPF is clever enough to handle something for me.

Imagine I have a collection containing objects. Each object is of the same known type and has two parameters. Name (a string) and Picked (a boolean).

The collection will be populated at run time.

I would like to build up a UI element at run time that will represent this collection as a series of checkboxes. I want the Picked parameter of any given object in the collection updated if the user changes the selected state of the checkbox.

To me, the answer is simple. I iterate accross the collection and create a new checkbox for each object, dynamically wiring up a ValueChanged event to captu开发者_运维百科re when Picked should be changed.

It has occured to me, however, that I may be able to harness some unknown feature of WPF to do this better (or "properly"). For example, could data binding be employed here?

I would be very interested in anyone's thoughts.

Thanks,

E

FootNote: The structure of the collection can be changed completely to better fit any chosen solution but ultimately I will always start from, and end with, some list of string and boolean pairs.


I would strongly recommend the ItemsControl, its behaviour is as close as you can get to the ASP.Net repeater control so it is very flexible.

Declare the item control as:

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

Then you can use the datatemplate to organise the data into a display format for the user

    <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>
     ...

Useful ItemsControl Links

  • http://drwpf.com/blog/itemscontrol-a-to-z/
  • http://www.galasoft.ch/mydotnet/articles/article-2007041201.aspx

I hope this helps you.


You can use Data Templates. Here's a good post about it.


This is exactly the kind of scenario WPF simplifies. Event-handlers- bah! Data-binding and data templates make this a cinch. I have constructed an example illustrating how you can do this.

Here is the code-behind, which declares a class to represent your items- PickedItem. I then create a collection of these items and populate it with some samples.

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;
    }
}

Now, let's look at the XAML mark-up for this window:

<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>

I create a ListBox to hold the items, and bind its ItemsSource property to the collection I created in the code-behind. Then, I provide the ListBox with an ItemTemplate, which determines how each PickedItem will be rendered. The DataTemplate in this case is as simple as a check-box and some text, both bound to the member variables on PickedItem. Now, when I check any of these items, the data in the underlying collection is modified, in real-time, with no event handlers needed. Ta-da!

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜