wpf mvvm - 有没有办法根据模型中的属性数量以编程方式创建文本框并绑定到其中的每个属性?

wpf mvvm - Is there a way to programmatically create textbox based on number of properties in model and bind to each of them in?

我有多个具有多个属性的对象,我想根据 属性 值显示或隐藏(或根据需要创建)这些属性。

例如: 型号:

     public class InputModel
{
    public string Name { get; set; }
    public string Id { get; set; }
    public string Type { get; set; }
    public bool Required { get; set; }
    public int Dpi { get; set; }
    public string Data { get; set; }
    public List<ColorModel> Filter { get; set; }
    public List<RenderModel> Render { get; set; }
    public List<LayoutModel> Layout { get; set; }
}

查看:

      <ItemsControl x:Name="InputsList"
                  Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Height="400">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel HorizontalAlignment="Center" Background="Beige" Margin="10">
                            
                            <TextBlock Text="{Binding Name, StringFormat='Name: {0}'}"/>
                            <TextBlock Text="{Binding Id, StringFormat='Id: {0}'}"/>
                            <TextBlock Text="{Binding Type, StringFormat='Type: {0}'}"/>
                        <CheckBox Grid.Column="1" Content="Required" Margin="0,5,0,0"
                                  IsChecked="{Binding ElementName=Required, Path=CheckBoxIsChecked}"/>
                            <TextBox Grid.Column="0" Grid.Row="4"
                                   Text="{Binding Dpi, StringFormat='Dpi: {0}'}"/>
                            <TextBlock Grid.Column="0" Grid.Row="5"
                                   Text="Render:"/>
                            
                    </StackPanel>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>

还有我的 ViewModel:

public class InputsListViewModel : Screen
{
    private IRootModel _rootModel;

    public InputsListViewModel(IRootModel rootModel)
    {
        _rootModel = rootModel;
    }

    private BindingList<InputModel> _inputs;

    public BindingList<InputModel> InputsList
    {
        get
        {
            _inputs = new (_rootModel.Inputs);
            return _inputs;
        }
        set
        {
            _inputs = value;
            NotifyOfPropertyChange(() => InputsList);
        }
    }

    private BindingList<RenderModel> _renders;

    public BindingList<RenderModel> RenderList
    {
        get 
        {
            _renders = new(_rootModel.Render);
            return _renders;
        }
        set 
        {
            _renders = value;
            NotifyOfPropertyChange(() => RenderList);
        }
    }

    private BindingList<LayoutModel> _layouts;

    public BindingList<LayoutModel> LayoutList
    {
        get
        {
            _layouts = new (_rootModel.Layout);
            return _layouts;
        }
        set
        {
            _layouts = value;
            NotifyOfPropertyChange(() => LayoutList);
        }
    }
}

我不需要在这里显示所有属性,只显示我在给定时间需要的属性。如果需要,我希望能够添加任何缺少的属性。

我是初学者,到目前为止我只知道如何手动创建我需要的字段并绑定到它们。

谢谢!

您可以使用 ItemContainerStyle 或单个属性隐藏整个项目,如 2 种不同方式所示

<ItemsControl ItemsSource="{Binding MyItems}">
    <ItemsControl.ItemContainerStyle>
        <Style>
            <Setter Property="Visibility" Value="{Binding ShowInUi, Converter={StaticResource BooleanToVisibilityConverter}}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Name, StringFormat='Name: {0}'}"/>
                <TextBlock Text="{Binding Id, StringFormat='Id: {0}'}"/>
                <TextBlock Text="{Binding Type, StringFormat='Type: {0}'}"/>
                    
                <!--possibility 1-->
                <TextBlock x:Name="AdditionalInfoText" Text="{Binding AdditionalInfo}"/>
                <!--possibility 2-->
                <TextBlock Text="{Binding SuperDuperValue}" Visibility="{Binding IsSuperDuperItem, Converter={StaticResource BooleanToVisibilityConverter}}"/>

            </StackPanel>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding AdditionalInfo}" Value="{x:Null}">
                    <Setter TargetName="AdditionalInfoText" Property="Visibility" Value="Collapsed"/>
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

对于一个区域中的所有文本块

<Style TargetType="TextBlock">
    <Style.Triggers>
        <Trigger Property="Text" Value="{x:Null}">
            <Setter Property="Visibility" Value="Collapsed"/>
        </Trigger>
        <DataTrigger Binding="{Binding Text.Length, RelativeSource={RelativeSource Self}}" Value="0">
            <Setter Property="Visibility" Value="Collapsed"/>
        </DataTrigger>
    </Style.Triggers>
</Style>