Xamarin 布尔转换器:尽管通过了转换器,但不更新页面

Xamarin Boolean converter: does not update page despite going through the converter

我正在尝试为我的页面使用转换器,但无济于事。

页面的重要部分是一个开关,两个列表视图。这些 Listview 是一个在另一个上面,根据开关的状态,应该只显示其中一个。在少数情况下,开关的状态也应该可以从应用程序中更改。

为此,我有一个布尔值 属性 (isPrimaryBin),如果为真,第一个列表视图 (primaryBinListView) 应该可见,第二个列表视图 (secondaryBinListView) 应该隐藏。

当 isPrimaryBin 变为 false 时,secondaryBinListview 可见,primaryListView 隐藏。

最后一件事,为了使其更直观,重要的是开关不应在 isPrimaryBin 为真时切换,而在 isPrimaryBin 为假时切换。 (由于标签在开关的两侧,它象征着从一个垃圾箱到另一个垃圾箱的开关)

起初我尝试创建第二个 属性,它会输出与 isPrimaryBin 相反的内容,但我永远不会点击 onPropertyChanged。所以我学会了如何制作转换器并制作了一个。起初,它不会击中它。我摆弄它,意识到我必须将它添加到资源字典中。然后它开始自己循环。页面陷入无限循环。我设法阻止了这种行为,但现在它不再更新页面。尽管开关已更改,但 primaryBinListview 始终可见,而 secondaryBinListView 始终隐藏。开关改变状态。它确实通过 属性。它确实通过转换器。我不知道为什么在它清楚地完成所有步骤时没有任何变化。

现在进入代码。让我们从 属性:

开始
public bool isPrimaryBin {
        get { return _isPrimaryBin; }
        set {
            if (_isPrimaryBin != value) {
                _isPrimaryBin = value;
                OnPropertyChanged();
            }
        }
    }

然后转换器

public class inverseBoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return !((bool)value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return !(bool)value;
    }
}

最后是相关的Xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:d="http://xamarin.com/schemas/2014/forms/design"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         mc:Ignorable="d"
         x:Class="Picking.Views.Inv2Page"
         Title="{Binding Title}"
         xmlns:local="clr-namespace:Picking.Helpers">

<ContentPage.Resources>
    <ResourceDictionary>
        <local:inverseBoolConverter x:Key="inverseBoolConverter" />
    </ResourceDictionary>
</ContentPage.Resources>

<ContentPage.Content>
    <Grid RowSpacing="0">
        <Grid Grid.Row="0">
            <Switch Grid.Column="1" OnColor="Orange" ThumbColor="Gray" IsVisible="{Binding isMoveGoods}" IsToggled="{Binding isPrimaryBin, Mode=TwoWay, Converter={StaticResource inverseBoolConverter}}"/
        </Grid>
        <ListView x:Name="ItemsListView" Grid.Row="1" 
            ItemsSource="{Binding Items}"
            VerticalOptions="FillAndExpand"
            HasUnevenRows="true"
            RefreshCommand="{Binding LoadItemsCommand}"
            IsPullToRefreshEnabled="true"
            IsRefreshing="{Binding IsBusy, Mode=OneWay}"
            CachingStrategy="RecycleElement"
            ItemTapped="ItemsListView_ItemTapped"
            Grid.RowSpan="2"
            IsVisible="{Binding isPrimaryBin}"
              >
        </ListView>

        <ListView x:Name="ItemsListViewTransfer" Grid.Row="1" 
            ItemsSource="{Binding Items}"
            VerticalOptions="FillAndExpand"
            HasUnevenRows="true"
            RefreshCommand="{Binding LoadItemsCommand}"
            IsPullToRefreshEnabled="true"
            IsRefreshing="{Binding IsBusy, Mode=OneWay}"
            CachingStrategy="RecycleElement"
            ItemTapped="ItemsListView_ItemTapped"
            Grid.RowSpan="2"
            IsVisible="{Binding isPrimaryBin, Converter={StaticResource inverseBoolConverter}}"
              >
        </ListView>
</ContentPage.Content>

</ContentPage>

我删除了与问题无关的任何内容(例如,列表视图的内容、额外的标签或与我的问题无关的任何内容)

这是我第一次使用转换器。我查看了关于如何使它们工作的多个指南,当没有任何工作但至少没有中断时,它让我陷入了这个奇怪的困境。

感谢您的帮助。

看起来你的两个 listView 在开关状态改变时加载相同的数据,所以看起来 UI 不会 change.Maybe 你可以显示你的 viewmodel.That更清晰。

下面是一个包含您的代码的简单示例,如果您想要的话?

ConvertModel(您可以更换自己的视图模型):

 class ConvertModel :INotifyPropertyChanged
{
    ObservableCollection<string> items = new ObservableCollection<string>();
    public ObservableCollection<string> Items { get { return items; } }
    private bool _isPrimaryBin;
    public bool isPrimaryBin
    {
        get { return _isPrimaryBin; }
        set
        {

            _isPrimaryBin = value;
            if (_isPrimaryBin)
            {
                items.Clear();
                items.Add("aaa");
                items.Add("bbb");
                items.Add("ccc");
                items.Add("ddd");
                items.Add("eee");
                items.Add("fff");
                items.Add("ggg");
            }
            else
            {
                items.Clear();
                items.Add("111");
                items.Add("222");
                items.Add("333");
                items.Add("444");
                items.Add("555");
                items.Add("666");
                items.Add("777");
            }
            OnPropertyChanged();

        }
    }

    public ConvertModel(bool isPr)
    {
        _isPrimaryBin = isPr;

        if (isPr)
        {
            items.Add("aaa");
            items.Add("bbb");
            items.Add("ccc");
            items.Add("ddd");
            items.Add("eee");
            items.Add("fff");
            items.Add("ggg");
        }
        else
        {
            items.Add("111");
            items.Add("222");
            items.Add("333");
            items.Add("444");
            items.Add("555");
            items.Add("666");
            items.Add("777");
        }

    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

page.xaml:

<ContentPage.Resources>
    <ResourceDictionary>
        <local:inverseBoolConverter x:Key="inverseBoolConverter" />
    </ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>

    <StackLayout Orientation="Vertical">
        <Switch Grid.Column="1" OnColor="Orange" ThumbColor="Gray"  IsToggled="{Binding isPrimaryBin, Mode=TwoWay, Converter={StaticResource inverseBoolConverter}}"></Switch>

        <ListView x:Name="ItemsListView" 
        ItemsSource="{Binding Items}"
        VerticalOptions="FillAndExpand"
        HasUnevenRows="true"
        IsPullToRefreshEnabled="true"
        CachingStrategy="RecycleElement"
        IsVisible="{Binding isPrimaryBin}"
         >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Label Text="{Binding .}"></Label>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <ListView x:Name="ItemsListViewTransfer" 
        ItemsSource="{Binding Items}"
        VerticalOptions="FillAndExpand"
        HasUnevenRows="true"
        IsPullToRefreshEnabled="true"
        CachingStrategy="RecycleElement"
        IsVisible="{Binding isPrimaryBin, Converter={StaticResource inverseBoolConverter}}"
          >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Label Text="{Binding .}"></Label>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage.Content>

page.xaml.cs:

public ConvertPage()
  {
      InitializeComponent();
      ConvertModel convertModel = new ConvertModel(false);
      BindingContext = convertModel;
  }

效果如: