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
属性,为其指定所需的任何名称。例:
因此,上面的XAML代码所做的是,我们将标签的命令绑定到整个父视图模型,当一个项位于由其ItemSource定义的DataTemplate中时,它的视图模型实际上就是正在用作数据模板的模型;这就是为什么我们将其源VM设置为整个父级的VM。
CommandParameter=“{Binding.}”
的逻辑与之前相同,我们绑定的是整个数据模板项,在本例中是为该元素呈现的MyCustomType
。这样,每次点击该标签时,我们都会将该标签及其数据传递给我们现在在VM中定义的命令。您是否尝试使用ObservableCollection而不是List?。您的“MyCustomType”imeplements INotifyPropertyChanged?在调试期间,您是否在输出窗口中看到任何绑定错误?有时它们很难被注意到。@BradleyUffner我已将所有文本输出复制到记事本上,并按异常
和错误
单词进行搜索。没有发生错误或异常。@JorgeeFernandezherrero是的,我也尝试过ObservableCollectionMyCustomType
是一种纯数据模型类型。它只保存字符串值,并且该值在运行时不会更改。在这种情况下,我为什么要为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;
}