Xaml 绑定对由开关切换的属性可见

Xaml 绑定对由开关切换的属性可见,xaml,xamarin.forms,Xaml,Xamarin.forms,我有一个绑定到列表中元素属性的开关。我想将按钮的IsVisible绑定到同一属性,但当开关更改属性时,按钮的可见性不会更改。我错过了什么 XAML: 正如Gerald在他的第一条评论中所写:您必须在您的设备模型(而不仅仅是在ViewModel中)上实现INotifyPropertyChanged接口 如果没有这个实现,视图中的元素就没有机会知道状态发生了变化(在您的例子中是按钮) 实施: public class Equipment: INotifyPropertyChanged { p

我有一个绑定到列表中元素属性的开关。我想将按钮的IsVisible绑定到同一属性,但当开关更改属性时,按钮的可见性不会更改。我错过了什么

XAML:


正如Gerald在他的第一条评论中所写:您必须在您的
设备
模型(而不仅仅是在ViewModel中)上实现
INotifyPropertyChanged
接口

如果没有这个实现,视图中的元素就没有机会知道状态发生了变化(在您的例子中是按钮)

实施:

public class Equipment: INotifyPropertyChanged
{
    public bool State
    {
        get => _state;
        set =>
        {
            _state = value;
            OnPropertyChanged();
        }
    }
    private bool _state;

    // OTHER PROPERTIES

    public event PropertyChangedEventHandler PropertyChanged;

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

调用方法
OnPropertyChanged()
非常重要。按钮的
IsVisible
属性识别更改并更新其值。

与其将两个内容绑定到一个属性,为什么不绑定单个项目(即开关)并使用XAML显示或隐藏按钮:

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibility" />
</Window.Resources>

<StackLayout>
    <ListView HorizontalOptions="FillAndExpand" ItemsSource="{Binding EquipmentList}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Orientation="Horizontal">
                        <Label Text="{Binding Name}" />
                        <Switch Name="toggleSwitch" IsToggled="{Binding State}" />
                        <Button
                        Command="{Binding BindingContext.DoCommand, Source={x:Reference TestPage}}"
                        CommandParameter="{Binding .}"
                        IsVisible="{Binding ElementName=toggleSwitch, Path=IsToggled, Converter={StaticResource BooleanToVisibilityConverter}"
                        Text="Click" />
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</StackLayout>

它可能不是StackLayout所在的窗口,但如果在参考资料部分中放置BooleantVisibilityConverter,则可以在XAML文件中使用它。 这意味着,如果属性名称在将来发生更改,您在用户界面中只需要更新一个位置,而且您还使用了XAML语言的强大功能


正如大家正确指出的那样,您需要在模型中实现INotifyPropertyChanged,以便更新交换机。

您是否实现了
INotifyPropertyChanged
接口?@GeraldVersluis是的INotifyPropertyChanged接口在viewmodel@GeraldVersluis然而,我想我必须对HandleeEquipment函数中的某些东西调用PropertyChanged()?在设备清单上调用它不起作用。我应该向OnPropertyChanged()传递什么?请添加实现属性
状态的项模型。只是为了确保一切都以正确的方式设置。@Joehl我添加了设备型号,如果这是你在课程中的意思的话!我认为只要在viewmodel中实现它,就可以监听对列表子属性的更改。
class Equipment
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool State { get; set; }

    public Equipment(int Id, string Name, bool State)
    {
        this.Id = Id;
        this.Name = Name;
        this.State = State;
    }
}
public class Equipment: INotifyPropertyChanged
{
    public bool State
    {
        get => _state;
        set =>
        {
            _state = value;
            OnPropertyChanged();
        }
    }
    private bool _state;

    // OTHER PROPERTIES

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibility" />
</Window.Resources>

<StackLayout>
    <ListView HorizontalOptions="FillAndExpand" ItemsSource="{Binding EquipmentList}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Orientation="Horizontal">
                        <Label Text="{Binding Name}" />
                        <Switch Name="toggleSwitch" IsToggled="{Binding State}" />
                        <Button
                        Command="{Binding BindingContext.DoCommand, Source={x:Reference TestPage}}"
                        CommandParameter="{Binding .}"
                        IsVisible="{Binding ElementName=toggleSwitch, Path=IsToggled, Converter={StaticResource BooleanToVisibilityConverter}"
                        Text="Click" />
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</StackLayout>