Привязка простого бизнес-класса к WPF UserControl

Я немного поработал с WPF пару лет назад, но, похоже, все забыл.

Предположим, у меня есть простой бизнес-класс, скажем, рабочий элемент TFS.

public class WorkItem
{
    public WorkItem(string name, DateTime date)
    {
        Name = name;
        Date = date;
    }

    public string Name { get; set; }
    public DateTime Date { get; set; }
}

Затем у меня есть список WorkItems, возможно, что-то вроде этого.

class WiList : ObservableCollection<WorkItem>
{
    public WiList () : base()
    {
        Add(new WorkItem("1", DateTime.Now));
        Add(new WorkItem("2", DateTime.Now));
    }
}

Затем у меня есть UserControl, представляющий WorkItem, что-то вроде этого.

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    x:Class="WrapPanelItemsControlTest.WorkItemControl"
    x:Name="UserControl"
    d:DesignWidth="640" d:DesignHeight="480" HorizontalAlignment="Left"
    VerticalAlignment="Top" Width="72" Height="40">

<StackPanel x:Name="LayoutRoot">
    <TextBlock x:Name="Name"/>
    <TextBlock x:Name="Date"/>
</StackPanel>

The main window contains a WrapPanel to hold the UserControls. My question is, how do I create a WrapPanel that binds to the WiList and displays the WorkItems? I remember doing something like this before, but for the death of me I can't remember how (probably something from Bea Costa's blog). Of course I can't find my old test code anywhere and seem to be expectionally bad at googling for examples.

Любая помощь приветствуется.


person Rubio    schedule 08.02.2010    source источник


Ответы (2)


Вероятно, вам нужно использовать ItemsControl для этого. WrapPanel можно использовать как панель макета для элементов коллекции. И если вам нужно только UserControl для отображения свойств одного объекта, то лучшим выбором будет использование DataTemplate. Вот немного XAML:

<Window.Resources>

    <DataTemplate x:Key="WorkItemTemplate" DataType="{x:Type local:WorkItem}">
        <StackPanel>
            <TextBlock Text="{Binding Name}"/>
            <TextBlock Text="{Binding Date}"/>
        </StackPanel>
    </DataTemplate>

</Window.Resources>

<Grid>

    <ItemsControl
        x:Name="itemsList"
        ItemTemplate="{StaticResource WorkItemTemplate}"
        >
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>

</Grid>

И в коде программной части привяжите ItemsControl к коллекции:

itemsList.ItemsSource = new WIList(); // or wherever the collection comes from

P.S. Инициализация ItemsSource и вообще доступ к элементам управления из кода программной части для привязки их к данным не является хорошей практикой. Вам понадобится класс ViewModel (Presenter) в качестве DataContext вашего окна. Если вы планируете какое-то время оставаться с WPF, мой совет: попробуйте использовать МВВМ.

П.П.С. Не забудьте реализовать INotifyPropertyChanged на WorkItem, если вам нужно, чтобы WPF не отставал от изменений значений свойств.

person arconaut    schedule 08.02.2010
comment
Инициализация ItemsSource из кода программной части не является хорошей практикой. Вы, вероятно, имели в виду это, но это может быть неясно из P.S. +1 =) - person Max Galkin; 09.02.2010

Сначала вам нужно связать экземпляр вашего класса WiList с ItemsSource ItemsControl, а затем применить DataTemplate для вашего WorkItem.

Аналогичная тема есть здесь.

Вы можете узнать больше о ItemsPanel ItemsControl здесь .

person micahtan    schedule 08.02.2010