如何在 Xamarin Forms MVVM Prism 的选择器中隐藏单个元素?
How to hide a single element in a picker in Xamarin Forms MVVM Prism?
我正在使用 MVVM 棱镜。我想在我的选择器中隐藏一个元素但是。我尝试使用 IsVisible 属性 但它不起作用。
这是我的 XAML
<Picker
HorizontalOptions="End"
WidthRequest="180"
HeightRequest="40"
IsVisible="{Binding IsDeductibleVisible, Mode=TwoWay}"
ItemsSource="{Binding Deductibles}"
ItemDisplayBinding="{Binding DisplayName}"
FontSize="14"
SelectedItem="{Binding SelectedDeductible}">
<Picker.Behaviors>
<behavior:EventToCommandBehavior
Command="{Binding Path=BindingContext.SelectDeductibleCommand, Source={x:Reference Name=CustomizePage}}"
EventName="SelectedIndexChanged"/>
</Picker.Behaviors>
</Picker>
这是我的视图模型。第一条记录是我要隐藏的记录。删除不是一个选项,因为 DeductiblesEnum.Zero 正在计算中使用。
Deductibles = new List<Deductible>
{
new Deductible{ Id = (int)DeductiblesEnum.Zero, Amount = 0, DisplayName = "NIL", IsDeductibleVisible = false },
new Deductible{ Id = (int)DeductiblesEnum.Thousand_100, Amount = 100000, DisplayName = "100,000 per insured" },
new Deductible{ Id = (int)DeductiblesEnum.Thousand_150, Amount = 150000, DisplayName = "150,000 per insured" },
new Deductible{ Id = (int)DeductiblesEnum.Thousand_200, Amount = 200000, DisplayName = "200,000 per insured" }
};
您的方案是从 ViewModel 的列表中删除一个项目,并且您正在使用 MVVM 设计模式。 Prism 是一个框架,不会对此代码产生任何影响。 IsVisible
属性 之所以不起作用,是因为它不正确 属性。 IsVisible
是 Picker
的 属性,将确定 Picker
是否可见。
您需要做的是更改 Picker.ItemSource
以删除不需要的值。有几种方法可以解决此问题,但我将向您展示我推荐的最 Xamarin 方法:
使用值转换器
Value Converters 是一个强大的工具,无需在 ViewModel 中编写大量代码即可将 ViewModel 中的对象映射到 UI。毕竟你的 ViewModel 应该不知道它所连接的任何视图。 Read about them here.
您的 ViewModel 看起来像这样,我已将您的列表转换为 ObservableCollection
,因为这是最佳做法
// BaseViewModel comes from Refractored.MVVMHelpers
public class DeductiblesViewModel : BaseViewModel
{
public ObservableCollection<Deductible> Deductibles { get; }
public DeductiblesViewModel()
{
Title = "Deductibles";
var deductibles = new List<Deductible>
{
new Deductible{ Id = (int)DeductiblesEnum.Zero, Amount = 0, DisplayName = "NIL", IsDeductibleVisible = false },
new Deductible{ Id = (int)DeductiblesEnum.Thousand_100, Amount = 100000, DisplayName = "100,000 per insured", IsDeductibleVisible = true },
new Deductible{ Id = (int)DeductiblesEnum.Thousand_150, Amount = 150000, DisplayName = "150,000 per insured", IsDeductibleVisible = true },
new Deductible{ Id = (int)DeductiblesEnum.Thousand_200, Amount = 200000, DisplayName = "200,000 per insured", IsDeductibleVisible = true }
};
Deductibles = new ObservableCollection<Deductible>(deductibles);
}
}
然后您将创建一个新的 ValueConverter
:
public class DeductibleVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value.GetType() != typeof(ObservableCollection<Deductible>))
{
throw new NotSupportedException($"Object must be of type: {typeof(ObservableCollection<Deductible>)}");
}
var deductibles = (ObservableCollection<Deductible>)value;
return deductibles.Where(d => d.IsDeductibleVisible).ToList();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException("We won't be using this method");
}
}
并将其添加到您的 XAML:
<ContentPage
...
/* Reference the xml namespace for your converter */
xmlns:converters="clr-namespace:YourNamespace.Converters"
...>
/* Add the converter as a resource to your page (or wherever you keep your resources) */
<ContentPage.Resources>
<ResourceDictionary>
<converters:DeductibleVisibilityConverter x:Key="deductibleVisibilityConverter"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout Padding="20">
<Label Text="Select your deductibles"/>
/* Add the converter to your item source */
<Picker ItemsSource="{Binding Deductibles, Converter={StaticResource deductibleVisibilityConverter}}"
ItemDisplayBinding="{Binding DisplayName}"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
现在您可以隐藏任何不想显示给 UI 的免赔额,但保留它们以供您计算!
我正在使用 MVVM 棱镜。我想在我的选择器中隐藏一个元素但是。我尝试使用 IsVisible 属性 但它不起作用。
这是我的 XAML
<Picker
HorizontalOptions="End"
WidthRequest="180"
HeightRequest="40"
IsVisible="{Binding IsDeductibleVisible, Mode=TwoWay}"
ItemsSource="{Binding Deductibles}"
ItemDisplayBinding="{Binding DisplayName}"
FontSize="14"
SelectedItem="{Binding SelectedDeductible}">
<Picker.Behaviors>
<behavior:EventToCommandBehavior
Command="{Binding Path=BindingContext.SelectDeductibleCommand, Source={x:Reference Name=CustomizePage}}"
EventName="SelectedIndexChanged"/>
</Picker.Behaviors>
</Picker>
这是我的视图模型。第一条记录是我要隐藏的记录。删除不是一个选项,因为 DeductiblesEnum.Zero 正在计算中使用。
Deductibles = new List<Deductible>
{
new Deductible{ Id = (int)DeductiblesEnum.Zero, Amount = 0, DisplayName = "NIL", IsDeductibleVisible = false },
new Deductible{ Id = (int)DeductiblesEnum.Thousand_100, Amount = 100000, DisplayName = "100,000 per insured" },
new Deductible{ Id = (int)DeductiblesEnum.Thousand_150, Amount = 150000, DisplayName = "150,000 per insured" },
new Deductible{ Id = (int)DeductiblesEnum.Thousand_200, Amount = 200000, DisplayName = "200,000 per insured" }
};
您的方案是从 ViewModel 的列表中删除一个项目,并且您正在使用 MVVM 设计模式。 Prism 是一个框架,不会对此代码产生任何影响。 IsVisible
属性 之所以不起作用,是因为它不正确 属性。 IsVisible
是 Picker
的 属性,将确定 Picker
是否可见。
您需要做的是更改 Picker.ItemSource
以删除不需要的值。有几种方法可以解决此问题,但我将向您展示我推荐的最 Xamarin 方法:
使用值转换器
Value Converters 是一个强大的工具,无需在 ViewModel 中编写大量代码即可将 ViewModel 中的对象映射到 UI。毕竟你的 ViewModel 应该不知道它所连接的任何视图。 Read about them here.
您的 ViewModel 看起来像这样,我已将您的列表转换为 ObservableCollection
,因为这是最佳做法
// BaseViewModel comes from Refractored.MVVMHelpers
public class DeductiblesViewModel : BaseViewModel
{
public ObservableCollection<Deductible> Deductibles { get; }
public DeductiblesViewModel()
{
Title = "Deductibles";
var deductibles = new List<Deductible>
{
new Deductible{ Id = (int)DeductiblesEnum.Zero, Amount = 0, DisplayName = "NIL", IsDeductibleVisible = false },
new Deductible{ Id = (int)DeductiblesEnum.Thousand_100, Amount = 100000, DisplayName = "100,000 per insured", IsDeductibleVisible = true },
new Deductible{ Id = (int)DeductiblesEnum.Thousand_150, Amount = 150000, DisplayName = "150,000 per insured", IsDeductibleVisible = true },
new Deductible{ Id = (int)DeductiblesEnum.Thousand_200, Amount = 200000, DisplayName = "200,000 per insured", IsDeductibleVisible = true }
};
Deductibles = new ObservableCollection<Deductible>(deductibles);
}
}
然后您将创建一个新的 ValueConverter
:
public class DeductibleVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value.GetType() != typeof(ObservableCollection<Deductible>))
{
throw new NotSupportedException($"Object must be of type: {typeof(ObservableCollection<Deductible>)}");
}
var deductibles = (ObservableCollection<Deductible>)value;
return deductibles.Where(d => d.IsDeductibleVisible).ToList();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException("We won't be using this method");
}
}
并将其添加到您的 XAML:
<ContentPage
...
/* Reference the xml namespace for your converter */
xmlns:converters="clr-namespace:YourNamespace.Converters"
...>
/* Add the converter as a resource to your page (or wherever you keep your resources) */
<ContentPage.Resources>
<ResourceDictionary>
<converters:DeductibleVisibilityConverter x:Key="deductibleVisibilityConverter"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout Padding="20">
<Label Text="Select your deductibles"/>
/* Add the converter to your item source */
<Picker ItemsSource="{Binding Deductibles, Converter={StaticResource deductibleVisibilityConverter}}"
ItemDisplayBinding="{Binding DisplayName}"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
现在您可以隐藏任何不想显示给 UI 的免赔额,但保留它们以供您计算!