是否可以根据Silverlight 4中的可绑定属性动态选择要呈现的控件?

时间:2010-10-01 18:13:54

标签: silverlight xaml silverlight-4.0 dynamic-data

我有一个带有ItemTemplate的ListBox,它使一个Grid呈现两列。第一列是TextBlock,第二列是ComboBox。

该想法是向用户呈现问题列表和用户可以从中选择答案的组合。这适用于这个xaml:

        <ListBox x:Name="QAListBox" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectedIndex="-1" 
             ItemsSource="{Binding Questions}" IsTabStop="True" TabIndex="5" 
             ScrollViewer.HorizontalScrollBarVisibility="Auto" Margin="10" BorderThickness="0">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid d:DesignWidth="931" d:DesignHeight="61" d:IsLocked="True" Margin="0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width=".80*" MinWidth="800"/>
                            <ColumnDefinition Width=".20*" MinWidth="200"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding Path=QuestionText}" Padding="10" FontSize="21.333" FontWeight="Bold" Margin="0" Grid.Column="0" d:IsLocked="True" />
                        <ComboBox ItemsSource="{Binding Path=AnswerAlternative}" 
                            SelectedValue="{Binding Path=QuestionsAndAnswers}" SelectedValuePath="AnswerAlternativeId" 
                            FontSize="21.333" FontWeight="Bold" Grid.Column="1" Margin="60,0,0,0" d:IsLocked="True" SelectionChanged="ComboBox_SelectionChanged">
                            <ComboBox.ItemTemplate>
                                <DataTemplate>
                                    <TextBox Text="{Binding Path=AnswerText, Mode=TwoWay}" BorderThickness="0">
                                        <TextBox.Background>
                                            <SolidColorBrush />
                                        </TextBox.Background>
                                    </TextBox>
                                </DataTemplate>
                            </ComboBox.ItemTemplate>
                        </ComboBox>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

将TextBox放入DataTemplate(而不是TextBlock)的原因是我第一次尝试允许用户输入自由文本以及从下拉列表中选择。然而,它有点工作,TextBox在ComboBox中。那不是我想要的。

是否可以使用“普通”TextBox渲染而不是基于某些可绑定属性的ComboBox?

因此,如果属性InputType == FreeText,则使用TextBox呈现视图,如果属性为Inputtype == Combo,则呈现如上所述?

吨。

1 个答案:

答案 0 :(得分:1)

针对您的特定问题的简单解决方案是在Visibility属性中包含两者并使用值转换器: -

public class EqualityToValueConverter<T> : IValueConverter
{
    public T FalseValue { get; set; }
    public T TrueValue { get; set; }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null)
            return FalseValue;
        else
            return value.ToString().Equals(parameter) ? TrueValue : FalseValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value != null && value.Equals(TrueValue) ? parameter : null;
    }
}

public class EqualityToVisibilityConverter : EqualityToValueConverter<Visibility> { }

然后你的Xaml看起来像: -

    <ListBox x:Name="QAListBox" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectedIndex="-1"     
         ItemsSource="{Binding Questions}" IsTabStop="True" TabIndex="5"     
         ScrollViewer.HorizontalScrollBarVisibility="Auto" Margin="10" BorderThickness="0">
        <ListBox.Resources>
          <local:EqualityToVisibilityConverter x:Key="converter"
            TrueValue="Visible" FalseValue="Collapsed" />
        </ListBox.Resources>    
        <ListBox.ItemTemplate>    
            <DataTemplate>    
                <Grid d:DesignWidth="931" d:DesignHeight="61" d:IsLocked="True" Margin="0">    
                    <Grid.ColumnDefinitions>    
                        <ColumnDefinition Width=".80*" MinWidth="800"/>    
                        <ColumnDefinition Width=".20*" MinWidth="200"/>    
                    </Grid.ColumnDefinitions>    
                    <TextBlock Text="{Binding Path=QuestionText}" Padding="10" FontSize="21.333" FontWeight="Bold" Margin="0" Grid.Column="0" d:IsLocked="True" />    
                    <ComboBox ItemsSource="{Binding Path=AnswerAlternative}"     
                        SelectedValue="{Binding Path=QuestionsAndAnswers}" SelectedValuePath="AnswerAlternativeId"     
                        FontSize="21.333" FontWeight="Bold" Grid.Column="1" Margin="60,0,0,0" d:IsLocked="True" SelectionChanged="ComboBox_SelectionChanged"
                        Visibility={Binding InputType, Converter={StaticResource converter}, ConverterParameter=Combo}">    
                    <TextBox Text="{Binding Path=AnswerText, Mode=TwoWay}" Grid.Column="1" Margin="60,0,0,0"
                      Visibility={Binding InputType, Converter={StaticResource converter}, ConverterParameter=FreeText}">             
                </Grid>    
            </DataTemplate>    
        </ListBox.ItemTemplate>    
    </ListBox>

更复杂的解决方案将使用ListBox的子类和覆盖或PrepareContainerForItemOverride来允许分配各种ItemTemplates。但是我觉得这个问题太过分了。