WPF,如何在加载时更改动态创建的 UI 组件的属性(可见性..)

WPF, How to change the properties (visibility.. ) of dynamically created UI components on load

我想更改动态填充的 UI 组件的属性。

这是我的示例 UI。动态创建的标签和三个文本框。 如果标签内容是 R11,我想更改第三个文本框的可见性。

如果标签为 R12

,则添加带有静态资源的组合框

这是我的示例代码

我的主屏幕XAML

<StackPanel>

    <control:MethodControl></control:MethodControl>


    <ContentControl Content="{Binding ChildViewModel}" />

</StackPanel>

MainViewModel

class MethodViewModel : ViewModelBase
{
    #region Properties
    private Method _method;
    private PropertyViewModel _childViewModel;
    #endregion


    #region Getter & Setters


    public PropertyViewModel ChildViewModel
    {
        get { return this._childViewModel; }
        set
        {
            if (this._childViewModel != value)
            {
                this._childViewModel = value;
                RaisePropertyChanged(() => ChildViewModel);
            }
        }
    }



    public Method Method
    {
        get { return _method; }

    }

    public ICommand UpdateCommand
    {
        get; private set;
    }
    #endregion

    #region Constructor
    /// <summary>
    /// Initialize a new interface of the MEthodViewModel class
    /// </summary>
    public MethodViewModel()
    {
        //test
        _method = new Method();
        PropertyViewModel pwm = new PropertyViewModel();
        pwm.CollectProperties(_method.Name, _method.Helper);
        ChildViewModel = pwm;
        UpdateCommand = new UpdateCommand(SaveChanges, () => string.IsNullOrEmpty(_method.Error));

    }
    #endregion


    #region Functions

    public void SaveChanges()
    {

        PropertyViewModel pwm = new PropertyViewModel();
        pwm.CollectProperties(_method.Name, _method.Helper);
        ChildViewModel = pwm;
    }

子视图模型

class PropertyViewModel : ViewModelBase
{

    private ObservableCollection<Property> _properties;

    public ObservableCollection<Property> Properties
    {
        get { return _properties; }
    }

    public PropertyViewModel(string method, string reflection)
    {
        _properties = new ObservableCollection<Property>();

        CollectProperties(method, reflection);
    }



    public void CollectProperties(string method, string reflection)
    {

        _properties.Clear();

        int methodindex = Array.IndexOf((String[])Application.Current.Resources["MethodNames"], method);


        switch (methodindex)
        {
            case 0:

                foreach (String prop in (String[])Application.Current.Resources["Result1"])
                {

                    PopulateProperty(prop, true);

                }
                break;

            default:

                foreach (String prop in (String[])Application.Current.Resources["Result2"])
                {

                    PopulateProperty(prop, true);

                }
                break;
        }

    }

    public PropertyViewModel()
    {
        _properties = new ObservableCollection<Property>();
    }

    private void PopulateProperty(string prop, bool p1)
    {
        Property temp = new Property(prop, "", 0, "");
        _properties.Add(temp);
    }



}

ChildViewModel XAML

<StackPanel >

    <ItemsControl ItemsSource = "{Binding Properties}" >

        <ItemsControl.ItemTemplate>
            <DataTemplate>

                <StackPanel Orientation = "Horizontal">
                    <Label Content="{Binding Name}"></Label>
                    <TextBox Text = "{Binding Path, Mode=TwoWay}" 
                        Width = "100" Margin = "3 5 3 5"/>

                    <TextBox Text = "{Binding StdDev, Mode=TwoWay}"
                                     Width = "100" Margin = "3 5 3 5"/>

                    <TextBox Text = "{Binding Unit, Mode=TwoWay}"
                                     Width = "100" Margin = "3 5 3 5"/>

                </StackPanel>

            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>


</StackPanel>        

和我的资源

<x:Array x:Key="MethodNames" Type="sys:String"
      xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <sys:String>MM1</sys:String>
    <sys:String>MM2</sys:String>
    <sys:String>MM3</sys:String>

</x:Array>

<x:Array x:Key="HelperMethods" Type="sys:String"
      xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <sys:String>HM1</sys:String>
    <sys:String>HM2</sys:String>
    <sys:String>HM3</sys:String>

</x:Array>

<x:Array x:Key="Result1" Type="sys:String"
      xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <sys:String>R11</sys:String>
    <sys:String>R12</sys:String>
    <sys:String>R13</sys:String>

</x:Array>

<x:Array x:Key="Result2" Type="sys:String"
      xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <sys:String>R21</sys:String>
    <sys:String>R22</sys:String>
    <sys:String>R23</sys:String>

</x:Array>


<DataTemplate DataType="{x:Type modelViews:PropertyViewModel}">
    <control:PropertyControl  />
</DataTemplate>
  1. 部分 UI 随组合框的选择而变化。

有些选项需要整个 3 个文本框,有些选项需要 1 个文本框,有些选项需要 1 个组合框,具体取决于标签名称。

如何将此 属性 添加到动态填充的用户控件中?

您可以向 DataTemplate 添加一个或多个触发器,例如:

<DataTemplate>
    <StackPanel Orientation = "Horizontal">
        <Label Content="{Binding Name}"></Label>
        <TextBox Text = "{Binding Path, Mode=TwoWay}" Width = "100" Margin="3 5 3 5"/>
        <TextBox Text="{Binding StdDev, Mode=TwoWay}" Width="100" Margin="3 5 3 5"/>
        <TextBox x:Name="third" Text="{Binding Unit, Mode=TwoWay}" Width="100" Margin="3 5 3 5"/>
        <ComboBox x:Name="combo" Visibility="Collapsed" />
    </StackPanel>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Name}" Value="R11">
            <Setter TargetName="third" Property="Visibility" Value="Collapsed" />
            <Setter TargetName="combo" Property="Visibility" Value="Visible" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

我找到了一个简单的方法来解决我的问题,所以让我添加它。 我在属性中添加可见性并将文本框可见性绑定到它。

这是可见性转换器的 bool

 public class BoolToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, 
            object parameter, CultureInfo culture)
        {
           return (bool) value ? Visibility.Visible : Visibility.Collapsed;
        }
     
        public object ConvertBack(object value, Type targetType, 
            object parameter, CultureInfo culture)
        {
            // Do the conversion from visibility to bool
        }
    }

资源

<converter:BoolToVisibilityConverter x:Key="converter"></converter:BoolToVisibilityConverter>

文本框

<TextBox Visibility="{Binding HasUnit, 
            Converter={StaticResource converter}}" />