如何使用 DataTemplate 在 ListBox 中进行自定义显示?
Posted
技术标签:
【中文标题】如何使用 DataTemplate 在 ListBox 中进行自定义显示?【英文标题】:How to have a custom display in ListBox with DataTemplate? 【发布时间】:2019-10-10 21:42:14 【问题描述】:我需要在 ListBox 中以特定布局显示卡片:
https://imgur.com/a/0U8eqTc
我试图找到一种方法来使用 2 种类型的 DataTemplate,但我不知道该怎么做。我决定制作一个包含 6 张卡片模板的模板(像这样):
https://imgur.com/VrOlYcR
这是我当前模板的样子:
<ControlTemplate x:Key = "CardTemplate" TargetType = "Button">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="4*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="Binding Path=Image"/>
<TextBlock Grid.Row="1" Text="Binding Path=Titre"/>
</Grid>
</ControlTemplate>
<DataTemplate x:Key="DataTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Grid.Row="0" Template="StaticResource CardTemplate"/>
<Grid Grid.Column="1" Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Template="StaticResource CardTemplate"/>
<Button Grid.Row="1" Template="StaticResource CardTemplate"/>
</Grid>
<Grid Grid.Column="0" Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Template="StaticResource CardTemplate"/>
<Button Grid.Row="1" Template="StaticResource CardTemplate"/>
</Grid>
<Button Grid.Column="1" Grid.Row="1" Template="StaticResource CardTemplate"/>
</Grid>
</DataTemplate>
我打算在 ListBox 中显示的内容:
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Name="ListBox" ItemTemplate="DynamicResource DataTemplate"
ScrollBar.Scroll="ScrollOnBottom">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
这是我的鳕鱼背后的基本工作原理:
class Cards
public List<Card> cards; // list of 6 Card objects
class Card
string title;
BitmapImage image;
public string Title get => title; set => title = value;
public BitmapImage Image get => image; set => image = value;
ObservableCollection<Cards> cc = new ObservableCollection<Cards>();
/*
Cards are already filled with 6 Card
cc filled with Cards
*/
formationListBox.ItemsSource = cc;
这就是问题所在,它显示了正确数量的卡片,但按钮是空的。我不知道如何将特定对象绑定到每个按钮。
【问题讨论】:
您必须使用属性,而不是字段。该按钮可以在您的视图模型中将其Command
绑定到ICommand
。了解 MVVM。
【参考方案1】:
举一个 Sinatr 评论的例子。你应该从 Mvvm 的角度来处理这个问题。首先你应该为这个窗口所在的视图添加一个视图模型。这将包含一个对象列表,DisplayCards
每个对象都将存储字符串和图像。
public class DisplayCard : INotifyPropertyChanged
private string _title;
public string Title
get return _title;
set
if (value != _title) _title = value; RaisePropertyChanged();
private string _cardImage;
public string CardImage
get return _cardImage;
set
if (value != _cardImage) _cardImage = value; RaisePropertyChanged();
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged([CallerMemberName] string propertyName = "")
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
public class YourViewVM : INotifyPropertyChanged
private ObservableCollection<DisplayCard> _cardCollection;
public ObservableCollection<DisplayCard> CardCollection
get return _cardCollection;
set
if (value != _cardCollection) _cardCollection = value; RaisePropertyChanged();
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged([CallerMemberName] string propertyName = "")
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
然后您需要将列表CardCollection
设置为ListBox 的ItemSource。然后使用数据模板将 DisplayCards 属性绑定到包含对象。
<ListBox Name="lbTodoList" HorizontalContentAlignment="Stretch" ItemSource="Binding CardCollection">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="4*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="Binding Image"/>
<TextBlock Grid.Row="1" Text="Binding Title"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
您需要确保将YourViewVM
设置为视图的DataContext。一个简单的搜索应该解决如何做到这一点。
以上内容应该足以让您重构代码以使其正常工作。
【讨论】:
以上是关于如何使用 DataTemplate 在 ListBox 中进行自定义显示?的主要内容,如果未能解决你的问题,请参考以下文章
[UWP]如何使用代码创建DataTemplate(或者ControlTemplate)
如何使用 DataTemplate 在 ListBox 中进行自定义显示?
如何设置控件属性(在DataTemplate和UserControl中)的绑定以使用ItemSource的给定属性?