wpf 在XAML中使用泛型:世界粮食计划署

5us2dqdw  于 2022-12-24  发布在  其他
关注(0)|答案(2)|浏览(175)

我尝试在代码中使用x:TypeArguments,这样我就可以在XAML中使用泛型。下面是一个如何使用它的示例:

<ComboBoxItem>
    <local:CustomKeyValuePair x:TypeArguments="x:String, x:String"
                              Key="Label To Show 01"
                              Value="Content To Show 01" />
</ComboBoxItem>

但是,我收到错误消息
错误MC6022:只有根标记可以指定属性“x:TypeArguments”。第34行位置43。
我还尝试在文件的顶部使用xmlns:x="http://schemas.microsoft.com/netfx/2009/xaml/presentation"而不是http://schemas.microsoft.com/winfx/2006/xaml,但这给了我一个不同的错误
错误MC3072:XML命名空间“http://schemas.microsoft.com/netfx/2009/xaml/presentation”中不存在属性“Class”。行1位置9。
有什么办法可以在世界粮食论坛实现这一目标?
MCVE所需代码

  • 自定义键值对.cs*
namespace GenericXamlMvce;

public record CustomKeyValuePair<K, V>
{
    public CustomKeyValuePair() { }

    public CustomKeyValuePair(K key, V value)
    {
        Key = key;
        Value = value;
    }

    public K Key { get; init; }

    public V Value { get; init; }

    public void Deconstruct(out K key, out V value)
    {
        key = Key;
        value = Value;
    }
}
  • 主窗口.xaml*
<Window x:Class="GenericXamlMvce.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:GenericXamlMvce"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0"
                               Grid.Row="0"
                               Text="Image: "
                               VerticalAlignment="Center"
                               Margin="5 0 2 0" />

        <ComboBox x:Name="DemoSelector"
                  Grid.Column="1"
                  Grid.Row="0"
                  SelectedIndex="0"
                  Margin="0 5 5 5"
                  DisplayMemberPath="Key"
                  SelectedValuePath="Value">
            <ComboBoxItem>
                <local:CustomKeyValuePair x:TypeArguments="x:String, x:String"
                                  Key="Label To Show 01"
                                  Value="Content To Show 01" />
            </ComboBoxItem>

            <ComboBoxItem>
                <local:CustomKeyValuePair x:TypeArguments="x:String, x:String"
                                          Key="Label To Show 02"
                                          Value="Content To Show 02" />
            </ComboBoxItem>
        </ComboBox>

        <TextBlock Grid.Column="0"
                   Grid.Row="1"
                   Grid.ColumnSpan="2"
                   Margin="10"
                   FontSize="20"
                   FontWeight="Bold"
                   Text="{Binding ElementName=DemoSelector, Path=SelectedValue}" />
    </Grid>
</Window>
siv3szwd

siv3szwd1#

有什么办法可以在世界粮食论坛实现这一目标?
不,恐怕不行。
该错误消息是正确的,因为只有根元素(如for example a window)可以指定x:TypeArguments属性。
为了能够在XAML中示例化和使用泛型CustomKeyValuePair<K, V>类型,您必须为类型参数的每个组合创建它的非泛型子类,例如:

public class StringIntCustomKeyValuePair : CustomKeyValuePair<string, int> { }
    • XAML格式:**
<local:StringIntCustomKeyValuePair />
bxpogfeg

bxpogfeg2#

(译文)
如果您愿意牺牲一些性能,请尝试反思。
XAML:

<Window x:Class="GenericXamlMvce.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:GenericXamlMvce"
        xmlns:s="clr-namespace:System;assembly=netstandard"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0"
                               Grid.Row="0"
                               Text="Image: "
                               VerticalAlignment="Center"
                               Margin="5 0 2 0" />

        <ComboBox x:Name="DemoSelector"
                  Grid.Column="1"
                  Grid.Row="0"
                  SelectedIndex="0"
                  Margin="0 5 5 5"
                  DisplayMemberPath="Key"
                  SelectedValuePath="Value">
            <ComboBoxItem>
                <local:CustomKeyValuePair K="{x:Type s:String}" 
                                          V="{x:Type s:String}" 
                                          Key="Label To Show 01"
                                          Value="Content To Show 01" />
            </ComboBoxItem>

            <ComboBoxItem>
                <local:CustomKeyValuePair K="{x:Type s:String}" 
                                          V="{x:Type s:String}" 
                                          Key="Label To Show 02"
                                          Value="Content To Show 02" />
            </ComboBoxItem>
        </ComboBox>

        <TextBlock Grid.Column="0"
                   Grid.Row="1"
                   Grid.ColumnSpan="2"
                   Margin="10"
                   FontSize="20"
                   FontWeight="Bold"
                   Text="{Binding ElementName=DemoSelector, Path=SelectedValue}" />
    </Grid>
</Window>

C编号:

public record CustomKeyValuePair
{
    public CustomKeyValuePair()
    {
        KeyValuePair = Create(K, V, Key, Value);
    }

    public object Key { get; init; }
    public object Value { get; init; }

    public Type K { get; init; }
    public Type V { get; init; }

    public object KeyValuePair { get; init; }

    public static object Create(Type t, Type v, object key, object value)
    {
        if (t == null || v == null)
        {
            return null;
        }
        var type = typeof(CustomKeyValuePair<,>).MakeGenericType(t, v);
        var cctor = type.GetConstructor(new Type[] { t, v });
        return cctor.Invoke(new object[] { key, value });
    }
    
    public CustomKeyValuePair<K, V> Convert<K, V>()
    {
        return (CustomKeyValuePair<K, V>)KeyValuePair;
    }
}

public record CustomKeyValuePair<K, V>
{
    public CustomKeyValuePair() { }

    public CustomKeyValuePair(K key, V value)
    {
        Key = key;
        Value = value;
    }

    public K Key { get; init; }

    public V Value { get; init; }

    public void Deconstruct(out K key, out V value)
    {
        key = Key;
        value = Value;
    }
}

相关问题