C# WPF/XAML:用户控件的数据绑定

C# WPF/XAML:用户控件的数据绑定,c#,wpf,xaml,data-binding,C#,Wpf,Xaml,Data Binding,因此,我正在创建“卡片”,以直观地表示StackPanel中的对象集合(我使用列表来保存这些对象): 主窗口XAML: <Window /* ... */> <StackPanel x:Name="Deck" Orientation="Horizontal" /> </Window> 在向Deck.Children添加一个元素后,其“视觉表示”确实会按预期显示在StackPanel中。然而,由于绑定Id和Value的标签仍然为空,DP似乎缺少一些东西

因此,我正在创建“卡片”,以直观地表示StackPanel中的对象集合(我使用列表来保存这些对象):

主窗口XAML:

<Window /* ... */>
    <StackPanel x:Name="Deck" Orientation="Horizontal" />
</Window>
在向
Deck.Children
添加一个元素后,其“视觉表示”确实会按预期显示在StackPanel中。然而,由于绑定
Id
Value
的标签仍然为空,DP似乎缺少一些东西


(将
x:Name=“crd”
赋予my UserControl,然后作为
ElementName
在绑定中使用它的想法已被插入,但在这种情况下可能会产生误导。)

无论何时要显示项的动态集合,都应该使用
ItemsControl

将XAML标记中的
StackPanel
替换为
ItemsControl

<ItemsControl ItemsSource="{Binding Cards}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <local:LoggerRepresentation />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
创建一个视图模型类,该类通过公共属性公开一组
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
            });
        }
    }
}

这种设计模式称为模型-视图-视图-模型(MVVM),是开发基于XAML的UI应用程序时推荐使用的模式。如果你在谷歌上搜索,你会发现更多的东西可以阅读和学习。

看起来你正在做的事情和以前在windows编程中做的一样。您应该检查MVVM和INotifyPropertyChanged接口。
不允许在
中使用,但在我将模板标记包装到
中时可以使用。这是正确的吗?我似乎还是弄错了,至少我现在的输出有错误:
System.Windows.Data错误:40:BindingExpression路径错误:“在”“对象”“视图模型”(HashCode=2077076)上找不到“值”属性。BindingExpression:Path=Value;DataItem='ViewModel'(HashCode=2077076);目标元素为“TextBlock”(名称=“”);目标属性为“Text”(类型为“String”)
中的“Cards”,引用公共
ObservableCollection Cards中的“Cards”{get;}=new ObservableCollection()?除非你在某个地方覆盖了DataContext,否则我仍然无法理解它应该是什么样子。我现在应该如何从主窗口向列表中添加项目呢?我在ViewModel类中添加了一个函数“Add()”,我只是将收到的项目路由到Cards属性中。对吗?你应该使用命令。但那是另一个故事。如果您有其他问题,请提出新问题。
public partial class LoggerRepresentation : UserControl
{
    public string Id { get; set; }
    public int Value { get; set; }
    /* ... */
}
<ItemsControl ItemsSource="{Binding Cards}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <local:LoggerRepresentation />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock Text="{Binding Path=Id}" />
<TextBlock Text="{Binding Path=Value} />
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
            });
        }
    }
}
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new ViewModel();
    }
}