WPF / XAML: привязка данных для пользовательских элементов управления - PullRequest
0 голосов
/ 07 сентября 2018

Итак, я создаю «карточки» для визуального представления коллекции объектов в StackPanel (для хранения этих объектов я использую список):

MainWindow XAML:

<Window /* ... */>
    <StackPanel x:Name="Deck" Orientation="Horizontal" />
</Window>

MainWindow C #:

public partial class MainWindow : Window
{
    /* ... */
    private void OnDataReceived(List<Reading> readings)
    {
        foreach(Reading r in readings)
        {
            Deck.Children.Add(new Card
            {
                Id = r.Id,
                Value = r.Value
            });
        }
    }
}

UserControl XAML:

<UserControl /* ... */ x:Name="crd">
    <Label Content="{Binding Path=Id, ElementName=crd}" />
    <Label Content="{Binding Path=Value, ElementName=crd} />
</UserControl>

UserControl C #:

public partial class LoggerRepresentation : UserControl
{
    public string Id { get; set; }
    public int Value { get; set; }
    /* ... */
}

После добавления одного элемента в Deck.Children его «визуальное представление» появляется в StackPanel, как и ожидалось. Однако в DP, похоже, чего-то не хватает, поскольку привязки Labels Id и Value остаются пустыми.

(Идея передать x:Name="crd" моему UserControl, а затем использовать его в привязке, так как ElementName был вставлен из ответа на кажущийся связанным вопрос , но в этом случае может вводить в заблуждение .)

1 Ответ

0 голосов
/ 07 сентября 2018

Вы должны использовать ItemsControl всякий раз, когда хотите отобразить динамическую коллекцию элементов.

Замените StackPanel в разметке XAML на ItemsControl:

<ItemsControl ItemsSource="{Binding Cards}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <local:LoggerRepresentation />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Привязка непосредственно к свойствам источника соответствующего объекта Card в UserControl (и замена элементов Label на TextBlocks):

<TextBlock Text="{Binding Path=Id}" />
<TextBlock Text="{Binding Path=Value} />

Создайте класс модели представления, который предоставляет доступ к коллекции Card объектов через открытое свойство и перенесите логику вашего приложения на это:

public class ViewModel
{
    public ObservableCollection<Card> Cards { get; } = new ObservableCollection<Card>();

    //...
    private void OnDataReceived(List<Reading> readings)
    {
        foreach (Reading r in readings)
        {
            Cards.Add(new Card
            {
                Id = r.Id,
                Value = r.Value
            });
        }
    }
}

Установите DataContext вида, где ItemsControl определен для экземпляра класса модели вида:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new ViewModel();
    }
}

Этот шаблон проектирования известен как Model-View-ViewModel (MVVM), и это рекомендуемый шаблон, который следует использовать при разработке приложений на основе XAML. Вы найдете намного больше, чтобы прочитать и узнать об этом, если ваш Google.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...