[英]WPF / XAML: Data Binding for UserControls
So I'm creating "cards" to visually represent a collection of objects within a StackPanel (which I'm using a list to hold these objects): 因此,我正在创建“卡片”以直观地表示StackPanel中的对象集合(我正在使用列表来保存这些对象):
MainWindow XAML: MainWindow XAML:
<Window /* ... */>
<StackPanel x:Name="Deck" Orientation="Horizontal" />
</Window>
MainWindow C#: 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 XAML:
<UserControl /* ... */ x:Name="crd">
<Label Content="{Binding Path=Id, ElementName=crd}" />
<Label Content="{Binding Path=Value, ElementName=crd} />
</UserControl>
UserControl C#: UserControl C#:
public partial class LoggerRepresentation : UserControl
{
public string Id { get; set; }
public int Value { get; set; }
/* ... */
}
Upon adding one element to Deck.Children
, its' visual representation does appear in the StackPanel as expected. 向
Deck.Children
添加一个元素Deck.Children
,其视觉表示确实如预期的那样出现在StackPanel中。 However, DP seems to lack something as the Labels binding Id
and Value
remain empty. 但是,DP似乎缺少某些东西,因为标签绑定
Id
和Value
保持为空。
(The idea to give x:Name="crd"
to my UserControl and then use it within the Binding as ElementName
has been plugged from the answer to a seemingly related question , but may be misleading in this case.) (将
x:Name="crd"
分配给我的UserControl,然后在Binding中将其用作ElementName
的想法已经从一个看似相关的问题的答案中插入了 ,但是在这种情况下可能会引起误解。)
You should use an ItemsControl
whenever you want to display a dynamic collection of items. 每当您要显示项目的动态集合时,都应使用
ItemsControl
。
Replace the StackPanel
in your XAML markup with an 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>
Bind directly to the source properties of the corresponding Card
object in the UserControl
(and replace the Label
elements with TextBlocks
): 直接绑定到
UserControl
相应Card
对象的源属性(并将Label
元素替换为TextBlocks
):
<TextBlock Text="{Binding Path=Id}" />
<TextBlock Text="{Binding Path=Value} />
Create a view model class that exposes a collection of Card
objects through a public property and move your application logic over to this one: 创建一个视图模型类,该视图模型类通过公共属性公开
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
});
}
}
}
Set the DataContext
of the view where the ItemsControl
is defined to an instance of the view model class: 将定义了
ItemsControl
的视图的DataContext
设置为视图模型类的实例:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new ViewModel();
}
}
This design pattern is known as Model-View-ViewModel (MVVM) and it's the recommended pattern to use when developing XAML based UI applications. 这种设计模式被称为模型-视图-视图模型(MVVM),它是在开发基于UI应用程序XAML使用推荐的模式。 You will find a lot more to read and learn about it if your Google.
如果您使用的是Google,那么您会发现更多阅读和了解的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.