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>
- 部分 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}}" />
我想更改动态填充的 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>
- 部分 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}}" />