XAML x: универсальный класс - PullRequest
0 голосов
/ 04 мая 2020

У меня есть этот класс

public class FeatureTabBase<T> : UserControl, IFeatureTab<T>
    where T : BaseModel
{
    public string TabGuid { get; set; }

    public T FeaturedElement
    {
        get { return (T)GetValue(FeaturedElementProperty); }
        set { SetValue(FeaturedElementProperty, value); }
    }

    // Using a DependencyProperty as the backing store for FeaturedElement.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty FeaturedElementProperty =
        DependencyProperty.Register("FeaturedElement", typeof(T), typeof(FeatureTabBase<T>), new PropertyMetadata(null));
}

, который реализует этот интерфейс

public interface IFeatureTab<T>
    where T : class
{
    T FeaturedElement { get; set; }
    string TabGuid { get; set; }
}

И этот экземпляр из него

public partial class MyClass : FeatureTabBase<MyType>
{
    public MyClass()
    {
        InitializeComponent();
    }
}

Но не знаю, как создать экземпляр это на XAML

image ">

Все, что я пытаюсь сделать, - это общая консоль c, которая может отображать некоторые страницы для моих различных типов элементов.

Я читал о x: TypeArguments на

https://docs.microsoft.com/en-us/dotnet/desktop-wpf/xaml-services/xtypearguments-directive

Но ничего не работает.

Есть идеи?

Ответы [ 3 ]

1 голос
/ 04 мая 2020

Добавьте x:TypeArguments к объявлению UserControl в XAML:

<ctr:FeatureTabBase
     x:Class="YourNamespace.MyClass"
     x:TypeArguments="local:MyType"
     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:ctr="clr-namespace:YourNamespace"
     xmlns:local="clr-namespace:YourNamespace"
     mc:Ignorable="d" 
     d:DesignHeight="450" d:DesignWidth="800">
    ...
</ctr:FeatureTabBase>
1 голос
/ 04 мая 2020

Вот элемент управления, который я использую, который, по крайней мере, проиллюстрирует концепцию.

Очевидно, что это не будет вырезано и вставлено для того, что вы имеете в виду.

Editrow позволяет мне легко выстроить ряд маркированных элементов управления внутри панели стека и добавить различные стандартизированные функции к элементам управления, которые я создаю.

public class EditRow : ContentControl
{
    public string LabelFor
    {
        get { return (string)GetValue(LabelForProperty); }
        set { SetValue(LabelForProperty, value); }
    }
    public static readonly DependencyProperty LabelForProperty = DependencyProperty.RegisterAttached(
                      "LabelFor",
                      typeof(string),
                      typeof(EditRow));
    public string LabelWidth
    {
        get { return (string)GetValue(LabelWidthProperty); }
        set { SetValue(LabelWidthProperty, value); }
    }
    public static readonly DependencyProperty LabelWidthProperty = DependencyProperty.RegisterAttached(
                      "LabelWidth",
                      typeof(string),
                      typeof(EditRow)
                      );
    public string PropertyWidth
    {
        get { return (string)GetValue(PropertyWidthProperty); }
        set { SetValue(PropertyWidthProperty, value); }
    }
    public static readonly DependencyProperty PropertyWidthProperty = DependencyProperty.RegisterAttached(
                      "PropertyWidth",
                      typeof(string),
                      typeof(EditRow)
                     );
    public EditRow()
    {
        this.IsTabStop = false;
    }
}

Я формирую шаблон в словаре ресурсов. (Существуют и другие варианты, включая пользовательский элемент управления generi c xaml)

<Style TargetType="{x:Type spt:EditRow}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type spt:EditRow}">
                <Grid Height="Auto">
                    <Grid.ColumnDefinitions>

                        <ColumnDefinition Width="{Binding RelativeSource={
                                      RelativeSource FindAncestor,
                                      AncestorType=spt:EditRow}, 
                                      Path=LabelWidth, TargetNullValue=2*}"/>

                        <ColumnDefinition Width="{Binding RelativeSource={
                                      RelativeSource FindAncestor,
                                      AncestorType=spt:EditRow}, 
                                      Path=PropertyWidth, TargetNullValue=3*}"/>

                    </Grid.ColumnDefinitions>

                    <TextBlock Text="{Binding RelativeSource={
                                      RelativeSource FindAncestor,
                                      AncestorType=spt:EditRow}, 
                                      Path=LabelFor}"
                                      HorizontalAlignment="Right"
                                      TextAlignment="Right"
                                      Margin="2,4,0,2"/>
                    <Border Padding="8,2,8,2" Grid.Column="1" BorderThickness="0">
                        <ContentPresenter>
                            <ContentPresenter.Resources>
                                <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource ErrorToolTip}"/>
                                <Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource ErrorToolTip}"/>
                                <Style TargetType="{x:Type DatePicker}" BasedOn="{StaticResource ErrorToolTip}"/>
                            </ContentPresenter.Resources>
                        </ContentPresenter>
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Использование:

                <ItemsControl>
                <spt:EditRow LabelFor="Name:" >
                        <TextBox Text="{Binding  EditVM.TheEntity.CustomerName, 
                            UpdateSourceTrigger=PropertyChanged,  
                            NotifyOnSourceUpdated=True,
                            NotifyOnValidationError=True,
                            Mode=TwoWay}"  />
                    </spt:EditRow>

                    <spt:EditRow LabelFor="Address:" >
                        <TextBox Text="{Binding  EditVM.TheEntity.Address1, 
                                                UpdateSourceTrigger=PropertyChanged, 
                                                NotifyOnSourceUpdated=True,
                                                NotifyOnValidationError=True,
                                                Mode=TwoWay}"  />
                    </spt:EditRow>

Обратите внимание, что у меня есть TextBox в качестве содержимого каждой из этих строк редактирования, но это может быть DatePicker или что-нибудь.

Вы можете связать это содержимое. Затем используйте тип данных в типе модели представления для переменных таблиц данных.

1 голос
/ 04 мая 2020

XAML не поддерживает генерики, поэтому ctrl:FeatureTabBase никогда не будет работать. Кроме того, вы не можете наследовать XAML-часть UserControl, если вы производите новый класс от существующего UserControl. Вы не можете использовать строго типизированные DataTemplates, поскольку они подключаются только к конкретному классу, указанному в типе. Вы должны принять другой подход. Может быть, упростить?

public class FeatureTab : UserControl
{
    public static readonly DependencyProperty FeaturedElementProperty =
        DependencyProperty.Register(
            "FeaturedElement",
            typeof(ModelBase),
            typeof(FeatureTab)
            , new PropertyMetadata(null));

    public string TabGuid { get; set; }

    public ModelBase FeaturedElement
    {
        get => (ModelBase) GetValue(FeaturedElementProperty);
        set => SetValue(FeaturedElementProperty, value);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...