Привязать ItemControl ItemSource к свойству зависимости UserControl - PullRequest
0 голосов
/ 06 декабря 2018

это мой самый первый выстрел при попытке создать пользовательский элемент управления со свойствами зависимости.Извините за недостаток знаний по этому вопросу.Я создал общий дизайн на одной из своих страниц, который я хотел бы перенести на многоразовый пользовательский элемент управления.

Исходный элемент управления на странице

Так что это элемент управленияЯ пытаюсь портировать в повторно используемый UserControl

<ToggleButton x:Name="filterButton" Background="{StaticResource BackgroundLightBrush}" BorderThickness="0">
    <fa:ImageAwesome x:Name="border"
                     Height="15"
                     Foreground="{StaticResource MediumBlueBrush}"
                     Icon="Filter"/>
</ToggleButton>

<Popup x:Name="popup" 
       AllowsTransparency="True"
       StaysOpen="False"
       PlacementTarget="{Binding ElementName=filterButton}"
       IsOpen="{Binding ElementName=filterButton,Path=IsChecked,Mode=TwoWay}">
    <Border BorderThickness="2" BorderBrush="{StaticResource MediumBlueBrush}" Background="{StaticResource BackgroundLightBrush}" CornerRadius="5">
        <ItemsControl ItemsSource="{Binding HeaderList}"
                      Background="{StaticResource BackgroundLightBrush}"
                      Margin="1">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" Margin="5">
                        <CheckBox IsChecked="{Binding IsChecked}"/>
                        <TextBlock Text="{Binding HeaderName}"/>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Border>
</Popup>

Вот изображение того, как выглядит этот элемент управления

enter image description here

Это мой код свойства зависимости

Здесь вы можете видеть, что я создал ObservableCollection типа RulesColumnHeader.Это источник элемента, который я пытаюсь установить для UserControl.

public partial class FilterDropDown : UserControl
{
    public ObservableCollection<RulesColumnHeader> ItemSource
    {
        get => (ObservableCollection<RulesColumnHeader>)GetValue(ItemSourceProperty);
        set => SetValue(ItemSourceProperty, value);
    }
    // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ItemSourceProperty =
        DependencyProperty.Register("ItemSource", typeof(ObservableCollection<RulesColumnHeader>), typeof(FilterDropDown), new FrameworkPropertyMetadata(null));

    public FilterDropDown()
    {
        InitializeComponent();
    }
}

UserControl

Вот моя "попытка" создания пользовательского элемента управления и привязкиисточник элемента к созданному мною свойству зависимости.

<UserControl x:Class="YAI.BomConfigurator.Desktop.Control.FilterDropDown"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:YAI.BomConfigurator.Desktop.Control"
         xmlns:fa="http://schemas.fontawesome.io/icons/"
         mc:Ignorable="d" 
         d:DesignHeight="50" d:DesignWidth="50">
<Grid>
    <ToggleButton x:Name="filterButton" Background="Transparent" BorderThickness="0">
        <fa:ImageAwesome x:Name="border"
                         Height="15"
                         Foreground="{StaticResource MediumBlueBrush}"
                         Icon="Filter"/>
    </ToggleButton>

    <Popup x:Name="popup" 
           AllowsTransparency="True"
           StaysOpen="False"
           PlacementTarget="{Binding ElementName=filterButton}"
           IsOpen="{Binding ElementName=filterButton,Path=IsChecked,Mode=TwoWay}">

        <Border BorderThickness="2" BorderBrush="{StaticResource MediumBlueBrush}" Background="{StaticResource BackgroundLightBrush}" CornerRadius="5">
            <ItemsControl ItemsSource="{Binding ItemSource, Source={local:FilterDropDown}}"
                          Background="{StaticResource BackgroundLightBrush}"
                          Margin="1">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal" Margin="5">
                            <CheckBox IsChecked="{Binding IsChecked}"/>
                            <TextBlock Text="{Binding HeaderName}"/>
                        </StackPanel>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Border>
    </Popup>
</Grid>

В моей привязке ItemSource к ItemsControl для части source = выдается сообщение об ошибке «Недопустимое расширение разметки, ожидаемый тип»объект 'фактический - FilterDropDown ".

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

Спасибо,

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Неправильно задано свойство Source привязки ItemsSource.

Заменить

ItemsSource="{Binding ItemSource, Source={local:FilterDropDown}}"

на

ItemsSource="{Binding ItemSource,
                      RelativeSource={RelativeSource AncestorType=UserControl}}"

Кроме того, оно является ненужным или даженеправильно объявлять ItemsSource как ObservableCollection.Используйте более общий тип, например IEnumerable:

public IEnumerable ItemSource
{
    get => (IEnumerable)GetValue(ItemSourceProperty);
    set => SetValue(ItemSourceProperty, value);
}

public static readonly DependencyProperty ItemSourceProperty =
    DependencyProperty.Register(
        nameof(ItemSource), typeof(IEnumerable), typeof(FilterDropDown));
0 голосов
/ 06 декабря 2018

Когда вы создаете пользовательский элемент управления, вы хотите определить свой ItemsSource как:

public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(nameof(ItemsSource), typeof(IEnumerable),
    typeof(xxx), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnItemsSourceChanged)));

    public IEnumerable ItemsSource
    {
        get
        {
            return (IEnumerable)GetValue(ItemsSourceProperty);
        }

        set
        {
            SetValue(ItemsSourceProperty, value);
        }
    }

OnItemsSourceChanged не требуется, я просто использовал его в коде, который я c & p'ed.

Вы также хотите, чтобы ваш контроль происходил от Контроля.НЕ UserControl.И, таким образом, .cs и .xaml не вкладываются одинаково.Они совершенно разные..Cs является автономным, и xaml находится в вашей папке Темы.

public class xxx : Control

и имеет статический конструктор:

static xxx()
{
    DefaultStyleKeyProperty.OverrideMetadata(typeof(xxx), new FrameworkPropertyMetadata(typeof(xxx)));
}

Затем в вашем XAML вы определите стиль, которыйнацеливается на xxx и в этом стиле устанавливает ControlTemplate.

Там, в общем, вы должны использовать привязку TemplateBinding для привязки к свойствам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...