C# 绑定到getter属性时,Xamarin IsVisible不会动态更新

C# 绑定到getter属性时,Xamarin IsVisible不会动态更新,c#,xaml,xamarin,mvvm,xamarin.forms,C#,Xaml,Xamarin,Mvvm,Xamarin.forms,我正试图通过将IsVisible绑定到getter属性来动态更新元素的可见性。但是,除非我刷新页面,否则IsVisible不会自动更改UI 以下是代码片段: xaml: C#: private string\u myItem; 公共字符串MyItem { get=>\u myItem; 设置 { 设置值(参考我的项目,值); } } 公共图书馆 { 获取{return MyItem==“Milk”;} } 公共事件属性更改事件处理程序属性更改; 受保护的虚拟void RaisePropert

我正试图通过将IsVisible绑定到getter属性来动态更新元素的可见性。但是,除非我刷新页面,否则IsVisible不会自动更改UI

以下是代码片段:

xaml:


C#:

private string\u myItem;
公共字符串MyItem
{
get=>\u myItem;
设置
{
设置值(参考我的项目,值);
}
}
公共图书馆
{
获取{return MyItem==“Milk”;}
}
公共事件属性更改事件处理程序属性更改;
受保护的虚拟void RaisePropertyChanged([CallerMemberName]字符串propertyName=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
受保护的bool SetValue(参考T字段,T值,[CallerMemberName]字符串propertyName=null)
{
布尔反应=假;
如果(字段==null||
!field.Equals(值))
{
字段=值;
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
响应=真;
}
返回响应;
}
更新MyItem后,将在代码中更新布尔属性。但是,在我手动重新呈现页面之前,UI元素不会自动显示


如果有人能解决此问题,我将不胜感激。

当您更改
MyItem
的值时,它不会为
IsMilkItem
引发
PropertyChanged
事件,因此用户界面永远不会被告知更新

public string MyItem
{
    get => _myItem;
    set
    {
        SetValue(ref _myItem, value);
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsMilkItem"));

    }
}

根据您的描述,您希望从选择器中选择项目,当选择项目为牛奶时,您希望标签控件可见,对吗

如果是,我修改了您的代码,您可以查看:

public partial class Page17 : ContentPage, INotifyPropertyChanged
{

    public ObservableCollection<string> MyItemOptions { get; set; }
    private string _MyItem;
    public string MyItem
    {
        get { return _MyItem; }
        set
        {
            _MyItem = value;
            if(_MyItem== "Milk")
            {
                IsMilkItem = true;
            }
            else
            {
                IsMilkItem = false;
            }
        }
    }
    private bool _IsMilkItem;
    public bool IsMilkItem
    {
        get { return _IsMilkItem; }
        set
        {
            _IsMilkItem = value;
            RaisePropertyChanged("IsMilkItem");
        }
    }

    public Page17 ()
    {
        InitializeComponent ();
        MyItemOptions = new ObservableCollection<string>()
        {
            "item 1",
            "item 2",
            "item 3",
            "Milk"
        };
        this.BindingContext = this;
    }

    public event PropertyChangedEventHandler PropertyChanged;


    public void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
public分部类页面17:ContentPage,INotifyPropertyChanged
{
公共ObservableCollection MyItemOptions{get;set;}
私有字符串_MyItem;
公共字符串MyItem
{
获取{return\u MyItem;}
设置
{
_MyItem=值;
如果(_MyItem==“Milk”)
{
IsMilkItem=真;
}
其他的
{
IsMilkItem=假;
}
}
}
私人住宅;
公共图书馆
{
获取{return\u IsMilkItem;}
设置
{
_IsMilkItem=值;
RaisePropertyChanged(“IsMilkItem”);
}
}
公共页17()
{
初始化组件();
MyItemOptions=新的ObservableCollection()
{
“项目1”,
“项目2”,
“项目3”,
“牛奶”
};
this.BindingContext=this;
}
公共事件属性更改事件处理程序属性更改;
public void RaisePropertyChanged(字符串propertyName)
{
PropertyChangedEventHandler处理程序=PropertyChanged;
if(处理程序!=null)
{
处理程序(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
更新:

您可以使用Labeltrigger来设置Label isvisible,而不需要使用IsMilkItem属性来设置Lable isvisible

<Picker x:Name="picker1" Title="Choose..." ItemsSource="{Binding MyItemOptions}" SelectedItem="{Binding MyItem}" />
        <Label Text="MyItem is Milk" IsVisible="False" >
            <Label.Triggers>
                <DataTrigger TargetType="Label" Binding="{Binding Source={x:Reference picker1},Path=SelectedItem}" Value="Milk">
                    <Setter Property="IsVisible"
                Value="True"/>
                </DataTrigger>
            </Label.Triggers>
        </Label>

以下是.cs:

public ObservableCollection<string> MyItemOptions { get; set; }
    private string _MyItem;
    public string MyItem
    {
        get { return _MyItem; }
        set
        {
            _MyItem = value;

        }
    }


    public Page17 ()
    {
        InitializeComponent ();
        MyItemOptions = new ObservableCollection<string>()
        {
            "item 1",
            "item 2",
            "item 3",
            "Milk"
        };
        this.BindingContext = this;
    }
公共ObservableCollection MyItemOptions{get;set;} 私有字符串_MyItem; 公共字符串MyItem { 获取{return\u MyItem;} 设置 { _MyItem=值; } } 公共页17() { 初始化组件(); MyItemOptions=新的ObservableCollection() { “项目1”, “项目2”, “项目3”, “牛奶” }; this.BindingContext=this; }

@YIFAN,如果我的回复对您有帮助,请记住将我的回复标记为答案,谢谢。嗨,Cherry,谢谢您的回复。我以前就是这样做的。但是,我觉得除了编写额外的代码行来设置布尔值之外,还必须有其他方法来实现这一点。就像knockout.js(也使用MVVM模式)具有计算的可观察值一样,Xamarin中是否有任何计算的可观察值可以自动触发UI?@YIFAN,另一种方法是使用触发器,请参见我的更新。我的函数SetValue()实际上引发了PropertyChanged事件alreadySetValue调用“MyItem”上的PropertyChanged。它不调用“IsMilkItem”上的PropertyChanged,这是您遇到问题的属性
<Picker x:Name="picker1" Title="Choose..." ItemsSource="{Binding MyItemOptions}" SelectedItem="{Binding MyItem}" />
        <Label Text="MyItem is Milk" IsVisible="False" >
            <Label.Triggers>
                <DataTrigger TargetType="Label" Binding="{Binding Source={x:Reference picker1},Path=SelectedItem}" Value="Milk">
                    <Setter Property="IsVisible"
                Value="True"/>
                </DataTrigger>
            </Label.Triggers>
        </Label>
public ObservableCollection<string> MyItemOptions { get; set; }
    private string _MyItem;
    public string MyItem
    {
        get { return _MyItem; }
        set
        {
            _MyItem = value;

        }
    }


    public Page17 ()
    {
        InitializeComponent ();
        MyItemOptions = new ObservableCollection<string>()
        {
            "item 1",
            "item 2",
            "item 3",
            "Milk"
        };
        this.BindingContext = this;
    }