You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.Forms:ListView单元格可见性绑定及子问题动态显示

嘿,我来帮你搞定这个动态显隐子问题的需求!结合你提到的MVVM架构和ObservableCollection数据源,咱们可以分几步来实现,既符合MVVM的规范,又能完美实现子问题随答案动态切换的效果:

第一步:优化数据模型(嵌套结构更清晰)

虽然你现在用的是扁平化的ObservableCollection,但改成嵌套结构会更便于管理子问题的关联关系。给你的AnsweredQuestion类添加子问题集合和一个控制显隐的布尔属性,同时在答案变更时自动更新这个属性:

public class AnsweredQuestion : INotifyPropertyChanged
{
    // 基础问题属性
    private string _questionText;
    public string QuestionText
    {
        get => _questionText;
        set { _questionText = value; OnPropertyChanged(); }
    }

    private string _selectedAnswer;
    public string SelectedAnswer
    {
        get => _selectedAnswer;
        set 
        { 
            _selectedAnswer = value; 
            OnPropertyChanged();
            // 答案变更时自动更新子问题可见性
            UpdateSubQuestionVisibility();
        }
    }

    public List<string> PossibleAnswers { get; set; } = new List<string>();

    // 子问题集合
    public ObservableCollection<AnsweredQuestion> SubQuestions { get; set; } = new ObservableCollection<AnsweredQuestion>();

    // 控制子问题显隐的核心属性
    private bool _shouldShowSubQuestions;
    public bool ShouldShowSubQuestions
    {
        get => _shouldShowSubQuestions;
        set { _shouldShowSubQuestions = value; OnPropertyChanged(); }
    }

    // 这里写你的业务逻辑:判断选中哪个答案时显示子问题
    private void UpdateSubQuestionVisibility()
    {
        // 示例:当选中"需要补充信息"这个选项时显示子问题
        ShouldShowSubQuestions = SelectedAnswer == "需要补充信息";
    }

    // 实现INotifyPropertyChanged,确保属性变更能通知UI
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
第二步:添加布尔值转可见性的转换器

因为WPF的Visibility枚举和布尔值不能直接绑定,我们需要一个转换器来完成转换:

public class BoolToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value is bool boolValue && boolValue ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value is Visibility visibility && visibility == Visibility.Visible;
    }
}

然后在XAML的资源中声明这个转换器:

<Window.Resources>
    <local:BoolToVisibilityConverter x:Key="BoolToVisibility"/>
</Window.Resources>
第三步:在ListView中实现动态显隐

接下来就是在ListView的ItemTemplate里绑定属性,让子问题区域根据ShouldShowSubQuestions自动切换显隐:

<ListView ItemsSource="{Binding YourQuestionCollection}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel Margin="0,5,0,5">
                <!-- 主问题区域 -->
                <TextBlock Text="{Binding QuestionText}" FontWeight="Bold" FontSize="14"/>
                <ComboBox ItemsSource="{Binding PossibleAnswers}" 
                          SelectedItem="{Binding SelectedAnswer, Mode=TwoWay}"
                          Margin="0,5,0,5"/>

                <!-- 子问题区域:绑定到显隐控制属性 -->
                <ItemsControl ItemsSource="{Binding SubQuestions}"
                              Visibility="{Binding ShouldShowSubQuestions, Converter={StaticResource BoolToVisibility}}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Margin="20,0,0,0">
                                <TextBlock Text="{Binding QuestionText}"/>
                                <ComboBox ItemsSource="{Binding PossibleAnswers}" 
                                          SelectedItem="{Binding SelectedAnswer, Mode=TwoWay}"
                                          Margin="0,5,0,5"/>
                            </StackPanel>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
第四步:ListView单元格可见性绑定到其他字段

如果是要让ListView的某一列单元格(比如GridView中的列)根据另一个字段显隐,同样用上面的转换器就可以。比如:

<ListView ItemsSource="{Binding YourQuestionCollection}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="问题内容" Width="200">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding QuestionText}"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <!-- 这个单元格的可见性绑定到ShouldShowExtraInfo属性 -->
            <GridViewColumn Header="额外备注" Width="150">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding ExtraNote}"
                                   Visibility="{Binding ShouldShowExtraInfo, Converter={StaticResource BoolToVisibility}}"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

这里只需要在AnsweredQuestion类中添加ShouldShowExtraInfo布尔属性,根据你的业务逻辑控制它的值即可。

内容的提问来源于stack exchange,提问作者Joshua Moon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:20:59