XAML数据触发器未更新

XAML数据触发器未更新,xaml,xamarin,xamarin.forms,Xaml,Xamarin,Xamarin.forms,当数据源中的属性更改时,我尝试更改按钮的颜色。根据IsFilterOn属性的初始值,初始化背景色可以正常工作,但当属性更改时,背景色不会更新 XAML <FlexLayout BindableLayout.ItemsSource="{Binding Filters}"> <BindableLayout.ItemTemplate> <DataTemplate> <Button>

当数据源中的属性更改时,我尝试更改按钮的颜色。根据
IsFilterOn
属性的初始值,初始化背景色可以正常工作,但当属性更改时,背景色不会更新

XAML

<FlexLayout BindableLayout.ItemsSource="{Binding Filters}">
    <BindableLayout.ItemTemplate>
        <DataTemplate>
            <Button>
                <Button.Triggers>
                    <DataTrigger Binding="{Binding IsFilterOn}" TargetType="Button" Value="False">
                        <Setter Property="BackgroundColor" Value="{Binding UpColour}" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding IsFilterOn}" TargetType="Button" Value="True">
                        <Setter Property="BackgroundColor" Value="{Binding DownColour}" />
                    </DataTrigger>
                </Button.Triggers>
            </Button>
        </DataTemplate>
    </BindableLayout.ItemTemplate>
</FlexLayout>

点击按钮可正确更新按钮的
IsFilterOn
属性(未显示代码),但用户界面不会改变以反映该属性。我做错了什么?

我们看不到您如何将
IsFilterOn
属性从
true
更新为
false
,但是如果您直接更改列表中某个
FilterModel
实例的属性,则不会调用属性更改事件

当您从列表中添加或删除某些内容时,
ObservableCollection
将执行属性更改事件,但它不监视对象的属性

您有两个选项,要么在更新
IsFilterOn
时从
FilterModel
调用属性更改事件,要么更改所有需要更改的属性值,然后手动执行列表上的属性更改。如果同时更新多个
FilterModel
s,则使用第二个选项可能会提高性能

备选案文1:

public class FilterModel : INotifyPropertyChanged {
    public string UpColour { get; set; }
    public string DownColour { get; set; }

    private bool _isFilterOn = false;
    public bool IsFilterOn {
        get { return _isFilterOn; }
        set {
            _isFilterOn = value;
            NotifyPropertyChanged(); // Anytime this property is changed Property Changed will be executed
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
备选案文2:

public class FilterViewModel {
    private ObservableCollection<FilterModel> _filters;
    public ObservableCollection<FilterModel> Filters {
        get => _filters ?? (_filters = new ObservableCollection<FilterModel>());
        set {
            _filters = value;
            NotifyPropertyChanged();
        }
    }

    public void ToggleFilters() {
        // some logic

        Filters[0].IsFilterOn = true; // Make all property changes

        NotifyPropertyChanged(nameof(Filters)); // Tell the UI that the list has been updated and to refresh the data
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
公共类FilterViewModel{
私有可观测收集过滤器;
公共可观测收集过滤器{
get=>\u filters???(\u filters=newobservetecollection());
设置{
_过滤器=值;
NotifyPropertyChanged();
}
}
公共无效切换过滤器(){
//一些逻辑
筛选器[0]。IsFilterOn=true;//进行所有属性更改
NotifyPropertyChanged(nameof(Filters));//告诉UI列表已更新,并刷新数据
}
公共事件属性更改事件处理程序属性更改;
私有void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName]字符串propertyName=”“)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
}

很可能是因为更改UI的函数未在UI线程上调用/运行。如果看不到您拥有的UI代码/您试图更新的UI代码,就很难提供更多帮助。“Device.beginInvokeMainThread”检查:您是正确的。那有点像掌心时刻,谢谢你的提醒。添加了PropertyChanged.Fody,一切都开始工作了。
public class FilterViewModel {
    private ObservableCollection<FilterModel> _filters;
    public ObservableCollection<FilterModel> Filters {
        get => _filters ?? (_filters = new ObservableCollection<FilterModel>());
        set {
            _filters = value;
            NotifyPropertyChanged();
        }
    }

    public void ToggleFilters() {
        // some logic

        Filters[0].IsFilterOn = true; // Make all property changes

        NotifyPropertyChanged(nameof(Filters)); // Tell the UI that the list has been updated and to refresh the data
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}