Действительно ли возможно связать Дочернее свойство Холста в XAML?

Один простой способ сделать это с кошками :

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]] в объем и используя его функцию объединения.

57
задан H.B. 10 January 2012 в 18:17
поделиться

4 ответа

Я не верю, что можно использовать привязку со свойством Children. Я действительно пытался сделать это сегодня, и у меня возникла ошибка, как и у вас.

Canvas - это очень элементарный контейнер. Он действительно не предназначен для такой работы. Вам следует изучить один из множества ItemsControls. Вы можете привязать модель данных ViewModel ObservableCollection к их свойству ItemsSource и использовать DataTemplates для обработки того, как каждый из элементов отображается в элементе управления.

Если вы не можете найти ItemsControl, который удовлетворительно отображает ваши элементы, вы возможно, придется создать настраиваемый элемент управления, который сделает то, что вам нужно.

9
ответ дан 24 November 2019 в 19:13
поделиться

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 .

19
ответ дан 24 November 2019 в 19:13
поделиться
<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>
140
ответ дан 24 November 2019 в 19:13
поделиться

Другие дали расширяемые ответы о том, как делать то, что вы на самом деле уже хотите делать. Я просто объясню, почему нельзя напрямую привязать Children .

Проблема очень проста - цель привязки данных не может быть свойством только для чтения, а Panel.Children только для чтения. Специальной обработки коллекций там нет. Напротив, ItemsControl.ItemsSource является свойством чтения / записи, даже если оно относится к типу коллекции - редкое явление для класса .NET, но требуется для поддержки сценария привязки.

25
ответ дан 24 November 2019 в 19:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: