C# Xamarin.Forms。XAML Label IsVisible条件未按预期进行计算

C# Xamarin.Forms。XAML Label IsVisible条件未按预期进行计算,c#,xaml,xamarin,xamarin.forms,C#,Xaml,Xamarin,Xamarin.forms,在我的项目中,我必须在一个页面上选择几个选项 每个选项都有一个类型MyCustomType,并声明了公共字符串Name属性 每个选项都通过标签显示。单击标签时,我会显示选项列表并选择它 当选择一个选项时,另一个选项的带有占位符文本的空标签(如选择一个项目)应显示在带有刚刚选择的选项的标签下方 我为每个选项使用单独的标签,而不是ListView元素(客户对特定外观的要求) 选择的数量是有限的,假设它等于四个 在我的viewmodel中,我声明了list属性(它已在viewmodel构造函数中初始化

在我的项目中,我必须在一个页面上选择几个选项

每个选项都有一个类型
MyCustomType
,并声明了公共字符串
Name
属性

每个选项都通过标签显示。单击标签时,我会显示选项列表并选择它

当选择一个选项时,另一个选项的带有占位符文本的空标签(如
选择一个项目
)应显示在带有刚刚选择的选项的标签下方

我为每个选项使用单独的标签,而不是ListView元素(客户对特定外观的要求)

选择的数量是有限的,假设它等于四个

在我的viewmodel中,我声明了list属性(它已在viewmodel构造函数中初始化):

问题是在标签声明中指定的IsVisible条件不起作用

将显示所有标签

未到达设置为
null-ToFalseBoolConverter
方法的
Convert
第一行的断点

我不明白为什么会这样


有什么想法吗?

这很有趣,但是下面的方法解决了我的问题

我已将
AllOptions
声明为
List
(不起作用),并声明为
observedcollection
(也不起作用)

我应该将我的列表声明为数组:

public MyCustomType[] AllOptions { get; }
我的标签开始正确显示,一个接一个地设置好


并且在处理它的值时,如果我得到null值,也就是说,我们已经到达填充选项的结尾。

,而不是尝试在那个问题上绑定,考虑使用既支持ItEntor又支持数据模板的布局类型。所以这类似于ListView/CollectionView/Stacklayout

例如,如果您决定使用StackLayout,例如:

<StackLayout
...
BindableLayout.ItemsSource="{Binding AllOptions}">
<BindableLayout.ItemTemplate>
        <DataTemplate>
            <Label Text="{Binding Name}" IsVisible="{Binding ., Converter={StaticResource NullToFalseBoolConverter}}">

        </DataTemplate>
    </BindableLayout.ItemTemplate>
</StackLayout>
编辑

因此,除了要将所选项传递给命令之外,还可以执行以下操作。我假设您的整个页面是一个完整的页面,但同样的概念适用于任何类型的页面

  • 在上设置一个
    x:Name
    属性,为其指定所需的任何名称。例:

  • 在标签上定义一个

  • 在绑定到页面的视图模型中,创建以下命令,如下所示:

    公共ICommand YourCommandName=>new命令(x=> 在这里(x))

  • 最后创建处理所选对象的方法

    public void YourCustomMethodHere(MyCustomType类型){}


  • 因此,上面的XAML代码所做的是,我们将标签的命令绑定到整个父视图模型,当一个项位于由其ItemSource定义的DataTemplate中时,它的视图模型实际上就是正在用作数据模板的模型;这就是为什么我们将其源VM设置为整个父级的VM。
    CommandParameter=“{Binding.}”
    的逻辑与之前相同,我们绑定的是整个数据模板项,在本例中是为该元素呈现的
    MyCustomType
    。这样,每次点击该标签时,我们都会将该标签及其数据传递给我们现在在VM中定义的命令。

    您是否尝试使用ObservableCollection而不是List?。您的“MyCustomType”imeplements INotifyPropertyChanged?在调试期间,您是否在输出窗口中看到任何绑定错误?有时它们很难被注意到。@BradleyUffner我已将所有文本输出复制到记事本上,并按
    异常
    错误
    单词进行搜索。没有发生错误或异常。@JorgeeFernandezherrero是的,我也尝试过ObservableCollection
    MyCustomType
    是一种纯数据模型类型。它只保存字符串值,并且该值在运行时不会更改。在这种情况下,我为什么要为
    MyCustomType
    实现INotifyPropertyChanged?@jorgernandezherrero我已经找到了解决方案,请检查您是否感兴趣。可能是因为您正在尝试访问它们。查看索引是数组工作的原因感谢您提供如此详细的答案。我将稍后检查此方法,如果它有效,我将接受您的答案作为解决方案。再次感谢。我真正的任务比我在问题上想象的要复杂,有一个条件显示第一项,而不是基于索引。单击标签后,我调用一个命令,并将标签索引传递给该命令,以将所选值放入相关标签。无论如何,我会接受你的回答,作为我所问问题的解决方案。我喜欢。谢谢。@Rafael我已经对我的答案进行了编辑,这有助于满足您的需要,我希望我正确地理解了您的情况。
    public class NullToFalseBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value != null;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    
    public MyCustomType[] AllOptions { get; }
    
    <StackLayout
    ...
    BindableLayout.ItemsSource="{Binding AllOptions}">
    <BindableLayout.ItemTemplate>
            <DataTemplate>
                <Label Text="{Binding Name}" IsVisible="{Binding ., Converter={StaticResource NullToFalseBoolConverter}}">
    
            </DataTemplate>
        </BindableLayout.ItemTemplate>
    </StackLayout>
    
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
    var element = (MyCustomType) value;
    if(element.Index != 0)
            return value != null;
    else
            return true;
    }