![](/img/trans.png)
[英]Wrappanel in ItemsControl.ItemsPanel throws XamlParseException
[英]ItemsControl with WrapPanel as ItemsPanel - combine a “static” child and ItemsSource
使用帶有WrapPanel設置為ItemsPanel的ItemsControl,我試圖實現此圖像中說明的內容:
XAML看起來像這樣(修改后使其更簡單):
<ItemsControl ItemsSource="{Binding Animals}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Margin="5">
<Image Source="{Binding ImageUrl}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
底層的ViewModel如下所示:
public class Zoo
{
public ObservableCollection<Animal> Animals { get; set; } = new ObservableCollection<Animal>();
public ICommand AddAnimal() => new DelegateCommand(() => Animals.Add(new Animal()));
}
public class Animal
{
public string ImageUrl { get; set; }
}
ItemsControl的DataContext設置為Zoo的一個實例,並填充4個Animals。
問題:如何添加一個看起來像其他元素的“靜態”子元素,是WrapPanel的子元素,並與其他子元素包裝? 具體來說,我希望最后一個元素是一個添加按鈕(上圖中顯示的綠色加號),它綁定到Zoo的AddAnimal Command屬性。
要求:
我考慮過:
附加信息:我使用:WPF,PRISM,C#6.0,.NET 4.0 Client Profile和MVVM模式。
有關這個問題的任何想法?
解:
@ kyriacos_k的答案為我解決了兩個小修改:
最后這對我有用:
<ItemsControl>
<ItemsControl.Resources>
<CollectionViewSource x:Key="AnimalCollection" Source="{Binding Animals}"/>
<behaviors:BindingProxy x:Key="Proxy" DataContext="{Binding}"/>
<DataTemplate DataType="{x:Type local:Animal}">
<Border Margin="5">
<Image Source="{Binding ImageUrl}" />
</Border>
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource AnimalCollection}}"/>
<Border Margin="5">
<Button Command="{Binding DataContext.AddAnimal, Source={StaticResource Proxy}}">
<Image Source="SourceToPlusSign"/>
</Button>
</Border>
</CompositeCollection>
</ItemsControl.ItemsSource>
</ItemsControl>
BindingProxy的代碼在這里(直接從WPF中的DataGridColumn的綁定可見性中獲取 ):
public class BindingProxy : Freezable
{
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
public object DataContext
{
get { return GetValue(DataContextProperty); }
set { SetValue(DataContextProperty, value); }
}
public static readonly DependencyProperty DataContextProperty =
DependencyProperty.Register("DataContext", typeof(object),
typeof(BindingProxy));
}
您可以使用CompositeCollection
以非常簡潔的方式完成此操作
<ItemsControl>
<ItemsControl.Resources>
<CollectionViewSource x:Key="AnimalCollection" Source="{Binding Animals}"/>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Margin="5">
<Image Source="{Binding ImageUrl}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource AnimalCollection}}"/>
<Border Margin="5">
<Button Command="{Binding AddAnimal}">
<Image Source="YourAddButtonSource"/>
</Button>
</Border>
</CompositeCollection>
</ItemsControl.ItemsSource>
</ItemsControl>
當然,如果您希望首先顯示添加按鈕,只需將Border
(包含Button
)的順序與CompositeCollection
標記中的CollectionContainer
進行交換。
看看CompositeCollection 。 它允許您向ItemsSource
綁定添加其他項:
<Window.Resources>
<CollectionViewSource x:Key="AnimalViewSource" Source="{Binding Animals}"/>
</Window.Resources>
<ItemsControl>
<ItemsControl.ItemsSource>
<CompositeCollection>
<local:Animal ImageUrl="somepath/plussign.png" />
<CollectionContainer Collection="{Binding Source={StaticResource AnimalViewSource}}"/>
</CompositeCollection>
</ItemsControl.ItemsSource>
... ItemsPanel, ItemsTemplate, etc. follow here ...
</ItemsControl>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.