Один простой способ сделать это с кошками :
import cats.implicits._
Map(1 -> "Hello").combine(Map(2 -> "Goodbye"))
//Map(2 -> Goodbye, 1 -> Hello)
Важно отметить, что обе карты должны быть одного типа (в данном случае, Map[Int, String]
).
Длинное объяснение:
combine
на самом деле не член Map. Импортируя cats.implicits, вы вводите в область действия встроенные моноидные экземпляры Map котов, а также некоторые неявные классы, которые включают краткий синтаксис.
Вышеуказанное эквивалентно следующему:
Monoid[Map[Int, String]].combine(Map(1 -> "Hello"), Map(2 -> "Goodbye"))
Где мы используем функцию Monoid "summoner" , чтобы получить экземпляр Monoid [Map [Int, String]] в объем и используя его функцию объединения.
Я не верю, что можно использовать привязку со свойством Children. Я действительно пытался сделать это сегодня, и у меня возникла ошибка, как и у вас.
Canvas - это очень элементарный контейнер. Он действительно не предназначен для такой работы. Вам следует изучить один из множества ItemsControls. Вы можете привязать модель данных ViewModel ObservableCollection к их свойству ItemsSource и использовать DataTemplates для обработки того, как каждый из элементов отображается в элементе управления.
Если вы не можете найти ItemsControl, который удовлетворительно отображает ваши элементы, вы возможно, придется создать настраиваемый элемент управления, который сделает то, что вам нужно.
ItemsControl
предназначен для создания динамических коллекций элементов управления пользовательского интерфейса из других коллекций, даже не связанных с пользовательским интерфейсом.
Вы можете создать шаблон ItemsControl
для рисования на Холсте
. Идеальным способом было бы установить опорную панель на Canvas
, а затем установить свойства Canvas.Left
и Canvas.Top
для непосредственных дочерних элементов. Мне не удалось заставить это работать, потому что ItemsControl
оборачивает своих дочерних элементов контейнерами, и трудно установить свойства Canvas
для этих контейнеров.
Вместо этого я использую сетку
в качестве корзины для всех элементов и рисую их каждый отдельно Холст
. При таком подходе есть некоторые накладные расходы.
<ItemsControl x:Name="Collection" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:MyPoint}">
<Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Ellipse Width="10" Height="10" Fill="Black" Canvas.Left="{Binding X}" Canvas.Top="{Binding Y}"/>
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Вот ' s код, который я использовал для настройки исходной коллекции:
List<MyPoint> points = new List<MyPoint>();
points.Add(new MyPoint(2, 100));
points.Add(new MyPoint(50, 20));
points.Add(new MyPoint(200, 200));
points.Add(new MyPoint(300, 370));
Collection.ItemsSource = points;
MyPoint
- это настраиваемый класс, который ведет себя так же, как версия System
. Я создал его, чтобы продемонстрировать, что вы можете использовать свои собственные классы.
И последняя деталь: вы можете привязать свойство ItemsSource к любой коллекции, какой захотите. Например:
<ItemsControls ItemsSource="{Binding Document.Items}"><!--etc, etc...-->
Дополнительные сведения о ItemsControl и его работе можно найти в следующих документах: Справочник по библиотеке MSDN ; Шаблон данных ; Серия статей доктора WPF по ItemsControl .
Вы можете привязать свойство ItemsSource к любой желаемой коллекции. Например:<ItemsControls ItemsSource="{Binding Document.Items}"><!--etc, etc...-->
Дополнительные сведения о ItemsControl и его работе можно найти в следующих документах: Справочник по библиотеке MSDN ; Шаблон данных ; Серия статей доктора WPF по ItemsControl .
Вы можете привязать свойство ItemsSource к любой желаемой коллекции. Например:<ItemsControls ItemsSource="{Binding Document.Items}"><!--etc, etc...-->
Дополнительные сведения о ItemsControl и его работе можно найти в следующих документах: Справочник по библиотеке MSDN ; Шаблон данных ; Серия статей доктора WPF по ItemsControl .
<ItemsControl ItemsSource="{Binding Path=Circles}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="White" Width="500" Height="500" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Ellipse Fill="{Binding Path=Color, Converter={StaticResource colorBrushConverter}}" Width="25" Height="25" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Top" Value="{Binding Path=Y}" />
<Setter Property="Canvas.Left" Value="{Binding Path=X}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
Другие дали расширяемые ответы о том, как делать то, что вы на самом деле уже хотите делать. Я просто объясню, почему нельзя напрямую привязать Children
.
Проблема очень проста - цель привязки данных не может быть свойством только для чтения, а Panel.Children
только для чтения. Специальной обработки коллекций там нет. Напротив, ItemsControl.ItemsSource
является свойством чтения / записи, даже если оно относится к типу коллекции - редкое явление для класса .NET, но требуется для поддержки сценария привязки.