Avalonia 根据绑定的数据类型动态选择模板

public partial class CommandParameterDialog : Window
{
    public CommandParameterDialog()
    {
        InitializeComponent();
        // 挂工厂事件
        var factory = this.FindResource("ParameterTemplateFactory") as RecyclingElementFactory;
        factory!.SelectTemplateKey += OnSelectTemplateKey;
    }

    private void OnSelectTemplateKey(object? sender, SelectTemplateEventArgs e)
    {
        e.TemplateKey = e.DataContext switch
        {
            DateTimeParameterViewModel => "DateTimeTemplate",
            StringParameterViewModel => "StringTemplate",
            EnumParameterViewModel => "EnumTemplate",
            Int32ParameterViewModel => "Int32Template",
            DoubleParameterViewModel => "DoubleTemplate",
            _ => throw new ArgumentOutOfRangeException()
        };
    }

    protected override void OnDataContextChanged(EventArgs e)
    {
        base.OnDataContextChanged(e);

        if (DataContext is CommandParameterDialogViewModel vm)
        {
            vm.CloseAction = result =>
            {
                Close(result);
            };
        }
    }
}

  <Design.DataContext>
        <viewModels:CommandParameterDialogViewModel></viewModels:CommandParameterDialogViewModel>
    </Design.DataContext>
    <Window.Resources>
        <RecyclingElementFactory x:Key="ParameterTemplateFactory">
            <RecyclingElementFactory.Templates>
                <!-- 模板:INT32 -->
                <DataTemplate x:Key="Int32Template" DataType="{x:Type viewModels:Int32ParameterViewModel}">
                    <StackPanel Margin="0,8">
                        <TextBlock Text="{Binding DisplayName}" FontWeight="Bold" />
                        <TextBox Text="{Binding Value, Mode=TwoWay}"
                                 Watermark="请输入整数" />
                    </StackPanel>
                </DataTemplate>

                <!-- 模板:DOUBLE -->
                <DataTemplate x:Key="DoubleTemplate" DataType="{x:Type viewModels:DoubleParameterViewModel}">
                    <StackPanel Margin="0,8">
                        <TextBlock Text="{Binding DisplayName}" FontWeight="Bold" />
                        <TextBox Text="{Binding Value, Mode=TwoWay}"
                                 Watermark="请输入小数" />
                    </StackPanel>
                </DataTemplate>
 <!-- 模板:STRING -->
                <DataTemplate x:Key="StringTemplate" DataType="{x:Type viewModels:StringParameterViewModel}">
                    <StackPanel Margin="0,8">
                        <TextBlock Text="{Binding DisplayName}" FontWeight="Bold" />
                        <TextBox Text="{Binding Value, Mode=TwoWay}"
                                 Watermark="请输入文本" />
                    </StackPanel>
                </DataTemplate>

                <!-- 模板:ENUM -->
                <DataTemplate x:Key="EnumTemplate" DataType="{x:Type viewModels:EnumParameterViewModel}">
                    <StackPanel Margin="0,8">
                        <TextBlock Text="{Binding DisplayName}" FontWeight="Bold" />
                        <ComboBox ItemsSource="{Binding Options}"
                                  SelectedItem="{Binding SelectedValue, Mode=TwoWay}" PlaceholderText="请选择" />
                    </StackPanel>
                </DataTemplate>

                <!-- 模板:DATETIME -->
                <DataTemplate x:Key="DateTimeTemplate" DataType="{x:Type viewModels:DateTimeParameterViewModel}">
                    <StackPanel Margin="0,8">
                        <TextBlock Text="{Binding DisplayName}" FontWeight="Bold" />
                        <DatePicker SelectedDate="{Binding Value, Mode=TwoWay}" />
                    </StackPanel>
                </DataTemplate>
            </RecyclingElementFactory.Templates>

        </RecyclingElementFactory>

    </Window.Resources>
    <DockPanel Margin="16">
        <!-- 底部按钮 -->
        <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right" Spacing="8">
            <Button Content="取消" Width="80" Command="{Binding CancelCommand}" />
            <Button Content="确定" Width="80" Command="{Binding ConfirmCommand}"
                    IsEnabled="{Binding IsValid}" />
        </StackPanel>

        <!-- 参数列表 -->
        <ScrollViewer HorizontalScrollBarVisibility="Disabled"
                      VerticalScrollBarVisibility="Auto">
            <ItemsRepeater ItemsSource="{Binding Parameters}" ItemTemplate="{StaticResource ParameterTemplateFactory}">
                <ItemsRepeater.Layout>
                    <StackLayout Orientation="Vertical" Spacing="8" />
                </ItemsRepeater.Layout>
            </ItemsRepeater>
        </ScrollViewer>
    </DockPanel>
posted @ 2025-09-22 10:59  Timskt  阅读(56)  评论(0)    收藏  举报