最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

MAUI ObservableCollection not triggering Converter - Stack Overflow

programmeradmin2浏览0评论

I have an ObservableCollection of strings:

public ObservableCollection<string> ChallengePartImageURLs { get; } = new ObservableCollection<string>();

Being populated/updated like this:

ChallengePartImageURLs.Clear();
foreach(var url in SelectedChallengePart.ImageURLs) {
    ChallengePartImageURLs.Add(url);
}

The UI is updated just fine, however, the converter is not triggered when the collection is changing:

IsVisible="{Binding ChallengePartImageURLs, Converter={StaticResource AnyImageCheckConverter}}"

The converter is working because if I change the ObservableCollection to an ObservableProperty it is perfectly triggered.

I have tried including a Binding to a ConverterParameter of an ObservableProperty but it is still not triggered.

Am I missing something or is there a way to trigger the converter?

Update

The converter is declared in XAML:

<ContentPage.Resources>
        <ResourceDictionary>
            <converters:AnyImageCheckConverter x:Key="AnyImageCheckConverter"/>
        </ResourceDictionary>
</ContentPage.Resources>

Used:

<CollectionView ItemsSource="{Binding ChallengePartImageURLs}" IsVisible="{Binding ChallengePartImageURLs, Converter={StaticResource AnyImageCheckConverter}}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Label Text="{Binding .}" />
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

The converter itself:

{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        try
        {
            if (value != null)
            {
                var list = (ObservableCollection<string>)value;
                if (list.Count > 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            return false;
        }
        catch (Exception ex)
        {
        }
        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

The Collection is only changed by clearing it and adding new items.

I have an ObservableCollection of strings:

public ObservableCollection<string> ChallengePartImageURLs { get; } = new ObservableCollection<string>();

Being populated/updated like this:

ChallengePartImageURLs.Clear();
foreach(var url in SelectedChallengePart.ImageURLs) {
    ChallengePartImageURLs.Add(url);
}

The UI is updated just fine, however, the converter is not triggered when the collection is changing:

IsVisible="{Binding ChallengePartImageURLs, Converter={StaticResource AnyImageCheckConverter}}"

The converter is working because if I change the ObservableCollection to an ObservableProperty it is perfectly triggered.

I have tried including a Binding to a ConverterParameter of an ObservableProperty but it is still not triggered.

Am I missing something or is there a way to trigger the converter?

Update

The converter is declared in XAML:

<ContentPage.Resources>
        <ResourceDictionary>
            <converters:AnyImageCheckConverter x:Key="AnyImageCheckConverter"/>
        </ResourceDictionary>
</ContentPage.Resources>

Used:

<CollectionView ItemsSource="{Binding ChallengePartImageURLs}" IsVisible="{Binding ChallengePartImageURLs, Converter={StaticResource AnyImageCheckConverter}}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Label Text="{Binding .}" />
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

The converter itself:

{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        try
        {
            if (value != null)
            {
                var list = (ObservableCollection<string>)value;
                if (list.Count > 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            return false;
        }
        catch (Exception ex)
        {
        }
        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

The Collection is only changed by clearing it and adding new items.

Share Improve this question edited Jan 22 at 16:34 Kasper Sommer asked Jan 22 at 16:13 Kasper SommerKasper Sommer 4631 gold badge8 silver badges20 bronze badges 2
  • please provide some more context - the small snipped you posted does not show us how/where the converter is attached. And please be more specific what you mean by "changing" the collection - are you adding/removing elements? Changing an existing element? Reassigning the entire collection? – Jason Commented Jan 22 at 16:17
  • Please show how did you declare the converter in your xaml. – Rafael Commented Jan 22 at 16:20
Add a comment  | 

1 Answer 1

Reset to default 2

The main reason that the converter is not triggered, as you discovered, is that the Converter will only be run after a PropertyChangedEvent. The ObservableCollection when items are cleared, added, or removed emit NotifyCollectionChangedAction.

What that means practically for your use case is to trigger a property changed event so that the converter will be run after you update the collection. The nice part about the way this behaves is that your page will not run the converter each time something is added or removed from you collection.

ChallengePartImageURLs.Clear();
foreach(var url in SelectedChallengePart.ImageURLs) {
  ChallengePartImageURLs.Add(url);
}
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ChallengePartImageURLs)));

Or if you are using MVVM toolkit, you can simplify the propteryChanged call

ChallengePartImageURLs.Clear();
foreach(var url in SelectedChallengePart.ImageURLs) {
  ChallengePartImageURLs.Add(url);
}
OnPropertyChanged(nameof(ChallengePartImageURLs));

I hope you find this helpful. I have had to implement this kind of behavior numerous times in my app. I found extending ObservableCollection to add this behavior quite beneficial.

发布评论

评论列表(0)

  1. 暂无评论