gpt4 book ai didi

c# - Xamarin.Forms。 XAML Label IsVisible 条件未按预期进行评估

转载 作者:行者123 更新时间:2023-12-04 15:19:34 27 4
gpt4 key购买 nike

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

每个选项都有一个类型 MyCustomType 并且声明了公共(public)字符串 Name 属性。

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

作为选择一个选项,带有占位符文本的空标签(例如选择一个项目),以便在标签下方使用Just Selected选项出现。

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

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

在我的 View 模型中,我声明了列表属性(它已在 View 模型构造函数中初始化):

public List<MyCustomType> AllOptions { get; }

在我的 XAML 页面标签中声明为:

<Label Text="{Binding AllOptions[0].Name}" >

<Label Text="{Binding AllOptions[1].Name}" IsVisible="{Binding AllOptions[0], Converter={StaticResource NullToFalseBoolConverter}}">

<Label Text="{Binding AllOptions[2].Name}" IsVisible="{Binding AllOptions[1], Converter={StaticResource NullToFalseBoolConverter}}">

<Label Text="{Binding AllOptions[3].Name}" IsVisible="{Binding AllOptions[2], Converter={StaticResource NullToFalseBoolConverter}}">

转换器 NullToFalseBoolConverter 看起来像这样:

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();
}
}

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

显示所有标签。

并且断点,设置在 NullToFalseBoolConverterConvert 方法的第一行没有到达。

我不明白为什么会这样。

有什么想法吗?

最佳答案

与其尝试绑定(bind),不如考虑使用既支持 ItemSource 又支持数据模板的布局类型。所以这类似于 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>

这种方法的美妙之处在于,由于您的标签都遵循相同的方法,您现在不仅可以 A) 编写更清晰的代码,还可以 B) 利用 MVVM 模式。现在,当然,这确实意味着每个控件也都应用了转换器;但是,如果仍然不想将它包含在第一个元素中,那么我们所要做的就是更改您的类型以包含索引属性。如果您想知道 Binding . 的语法是什么意思是,这意味着我们只是为该元素绑定(bind)该集合的整个对象。

public int Index {get; set;}

在构建数组的地方设置它,然后在转换器中,您所要做的就是:

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;
}

编辑

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

  1. 设置 x:Name上的属性,给它任何你想要的名字。例如:

    <内容页...x:Name="root">

  2. 定义一个 <GestureRecognizer>在你的标签上

<Label Text="{Binding Name}" IsVisible="{Binding ., Converter={StaticResource NullToFalseBoolConverter}}"> <Label.GestureRecognizers> <TapGestureRecognizer Command="{Binding BindingContext.YourCommandName, Source={x:Reference root}}" CommandParameter="{Binding .}"/> </Label.GestureRecognizers>

  1. 在绑定(bind)到页面的 View 模型中,创建以下命令,如下所示:

    public ICommand YourCommandName => 新命令(x =>YourCustomMethodHere(x));

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

    public void YourCustomMethodHere(MyCustomType 类型){}

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

关于c# - Xamarin.Forms。 XAML Label IsVisible 条件未按预期进行评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63631648/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com