У меня есть ItemsControl, данные которого привязаны к списку decimal. Мне нужно добавить один дополнительный элемент управления к ItemsControl (возможность указать номер вручную). Есть ли способ сделать это в XAML? Я знаю, что могу вручную добавить элемент в код позади, но я пытаюсь немного лучше понять WPF и хочу посмотреть, есть ли декларативный способ сделать это.
Обратите внимание, что изменение списка, к которому я привязываюсь, чтобы он включал дополнительную кнопку (возможно, путем изменения списка string вместо decimal), не является хорошей альтернативой, потому что я хочу прикрепить команду к этой последней кнопке.
Кроме того, добавление дополнительной кнопки после ItemsControl тоже не лучший вариант, потому что мой элемент управления использует UniformGrid, и мне нужен дополнительный элемент управления в той же сетке.
Вот мой XAML:
<ItemsControl ItemsSource = "{Binding PossibleAmounts}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Name = "ButtonsGrid">
</UniformGrid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button>
<TextBlock Text = "{Binding StringFormat='\{0:C\}'}"/>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
По сути, мне нужна еще одна кнопка в UniformGrid.





Для этой цели вы можете использовать класс CompositeCollection, он объединяет несколько коллекций или отдельные элементы в качестве ItemsSource для ItemsControl.
Есть хороший пример в статье MSDN или вот еще один:
<Grid xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sys = "clr-namespace:System;assembly=mscorlib"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml">
<Grid.Resources>
<x:Array x:Key = "intData" Type = "{x:Type sys:Int32}">
<sys:Int32>1</sys:Int32>
<sys:Int32>2</sys:Int32>
<sys:Int32>3</sys:Int32>
</x:Array>
<x:Array x:Key = "stringData" Type = "{x:Type sys:String}">
<sys:String>Do</sys:String>
<sys:String>Re</sys:String>
<sys:String>Mi</sys:String>
</x:Array>
</Grid.Resources>
<ListBox>
<ListBox.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection = "{StaticResource intData}"/>
<CollectionContainer Collection = "{StaticResource stringData}"/>
<ListBoxItem>One more item!</ListBoxItem>
<ListBoxItem>Two more items!</ListBoxItem>
</CompositeCollection>
</ListBox.ItemsSource>
</ListBox>
</Grid>
Есть ли альтернатива WindowsRT? Я не вижу CompositeCollection в XAML приложения Win8, поэтому предполагаю, что сам объект недоступен ...
Однако проблема с CompositeCollection заключается в том, что он не наследует родительский элемент DataContext, поэтому вы не сможете написать:
<CollectionContainer Collection = {Binding ...}" />
внутри - вернее, пусть позволит, но от этого ничего не выйдет. Поскольку исходный пост требовал этого - {Binding PossibleAmounts} - вместо привязки к StaticResource - это не совсем решение.
Видеть:
http://blogs.msdn.com/nickkramer/archive/2006/08/18/705116.aspx
http://www.vistax64.com/avalon/90-compositecollections-collectioncontainer-binding-issue.html
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/bd1a78c1-67ef-4d1e-9cbe-70bbe8eb8b44/
Эта проблема решается путем добавления к ресурсам объекта freezable, который хранит привязку и служит источником для привязки свойства коллекции.
@DmitryTashkinov было бы интересно объяснить почему.
@DmitryTashkinov Не могли бы вы рассказать немного, как мы можем этого добиться?
Ой, ребята, прошли годы. Так почему бы вам не добавить ресурс <CollectionViewSource x: Key = "ExtraItems" Source = "{Binding Items}" /> и внутри CompositeCollection добавить <CollectionContainer Collection = "{Binding Source = {StaticResource ExtraItems}}" />
Ссылаясь на комментарий @DmitryTashkinov о freezable - см. stackoverflow.com/questions/2692175/freezable-datacontext, stackoverflow.com/questions/26364979/…, stackoverflow.com/questions/19144410/…
Блестяще! Не ожидал, что такая вещь будет реализована как стандартная функция в WPF!