【问题标题】:StackPanel Dynamic Binding of Visibility and IsEnabled Properties via ConvertersStackPanel 通过转换器动态绑定 Visibility 和 IsEnabled 属性
【发布时间】:2012-11-22 03:42:36
【问题描述】:

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

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

  1. 子项垂直方向的父 StackPanel(标签和输入字段的集合以模拟表单)
  2. 子节点 StackPanel,子节点为水平方向(标签和输入字段)

主要思想是每个标签只有一个输入字段:日期选择器、组合、文本或任何其他字段。结果,我创建了一个标签和一个带有多个控件的网格。我通过转换器操作输入控件的 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;
}

【问题讨论】:

    标签: wpf dynamic binding properties stackpanel


    【解决方案1】:

    我会使用 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>
    

    【讨论】:

    • 谢谢,我需要如何将数据传递给 DataTemplate(TextBoxTemplate、DateTimeTemplate 等)来执行绑定?
    • @EARNEST ContentControl.DataContext默认会被模板对象继承,也可以绑定ContentControl.Content属性
    【解决方案2】:

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

    您可以轻松地将用户控件添加到 StackPanel 中,方法是将其添加到其 Children 属性中。

    【讨论】:

    • 我采用了一种略有不同的方法 - @Rachel 和您的解决方案的混合。我用 DataTempaltes 创建了一个单独的用户控件和一个资源字典。谢谢
    猜你喜欢
    • 2010-09-30
    • 2012-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 2018-07-11
    相关资源
    最近更新 更多