StackPanel通过转换器动态绑定可见性和IsEnabled属性

时间:2012-12-04 13:35:55

标签: wpf dynamic binding properties stackpanel

我的小目标是实现动态的移动生成控件并关联它们各自的属性,例如Visibility和IsEnabled。

必须将控件插入StackPanel。并且基于某些条件,子节点属性会发生变化。我使用了以下nasted StackPanel结构:

  1. 具有垂直方向儿童的父StackPanel(标签广告输入字段集合以模拟表单)
  2. 子节点StackPanel,水平方向为Children(标签和输入字段)
  3. 主要思想是每个标签只有一个输入字段:日期选择器,组合,文本或任何其他。结果,我创建了一个Label和一个包含多个Controls的Grid。我通过转换器操作输入控件的Visibility和IsEnabled属性。

    这是一个问题:是否可以通过其他方式(更有效/美观)实现所有这些?建设性的批评和建议非常受欢迎:)

    提前谢谢。

    XAML:

    <StackPanel Grid.Row="1" Orientation="Vertical">
        <ItemsControl ItemsSource="{Binding DataClass}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" Margin="0, 5, 0, 0" >
                        <Label Content="{Binding KeyName}" Width="150"/>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="190"/>
                            </Grid.ColumnDefinitions>
                            <DatePicker Text="{Binding Value}"
                                Visibility="{Binding Type, Converter={StaticResource TypeVisiblity}, ConverterParameter='DateTime'}"
                                IsEnabled="{Binding RelativeSource={x:Static RelativeSource.Self}, Converter={StaticResource VisibilityEnabled}}"/>
                            <ComboBox Text="{Binding Value}" 
                                Visibility="{Binding Type, Converter={StaticResource TypeVisiblity}, ConverterParameter='Lookup'}"
                                IsEnabled="{Binding RelativeSource={x:Static RelativeSource.Self}, Converter={StaticResource VisibilityEnabled}}"/>
                            <TextBox Text="{Binding Value}" 
                                Visibility="{Binding Type, Converter={StaticResource TypeVisiblity}, ConverterParameter='Number'}"
                                IsEnabled="{Binding RelativeSource={x:Static RelativeSource.Self}, Converter={StaticResource VisibilityEnabled}}"/>
                            <TextBox Text="{Binding Value}" 
                                Visibility="{Binding Type, Converter={StaticResource TypeVisiblity}, ConverterParameter='Text'}"
                                IsEnabled="{Binding RelativeSource={x:Static RelativeSource.Self}, Converter={StaticResource VisibilityEnabled}}"/>
                        </Grid>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>
    

    可见性转换器:

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool isMatched;
            string type,
                   controlType;
    
            // Safe Convert.
            type = System.Convert.ToString(value);
            controlType = System.Convert.ToString(parameter);
    
            if (string.IsNullOrEmpty(type) || string.IsNullOrEmpty(controlType))
            {
                return Visibility.Hidden;
            }
    
            // Check matching.
            isMatched = string.Equals(type, controlType, StringComparison.CurrentCultureIgnoreCase);
    
            return isMatched ? Visibility.Visible : Visibility.Hidden;
        }
    

    IsEnabled转换器:

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Control control;
    
        control = value as Control;
    
        if (control == null)
        {
            return false;
        }
    
        return control.Visibility == Visibility.Visible;
    }
    

2 个答案:

答案 0 :(得分:0)

创建一个用户控件,将DatePicker,ComboBox,TextBox等作为用户界面,并在此用户控件后面的代码中实现所有必要的逻辑。您可以添加依赖项属性来实现没有转换器的逻辑。

您可以通过将用户控件添加到其Children属性中来轻松地将用户控件添加到StackPanel中。

答案 1 :(得分:0)

我会使用ContentControl并将ContentTemplate设置为样式

<ContentControl>
    <ContentControl.Style>
        <Style TargetType="{x:Type ContentControl}">
            <!-- Default Template -->
            <Setter Property="ContentTemplate" 
                    Value="{DynamicResource TextBoxTemplate}" />

            <Style.Triggers>
                <DataTrigger Binding="{Binding Type}" Value="DateTime">
                    <Setter Property="ContentTemplate" 
                            Value="{DynamicResource DateTimeTemplate}" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Type}" Value="Lookup">
                    <Setter Property="ContentTemplate" 
                              Value="{DynamicResource ComboBoxTemplate}" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>