将IsVisible绑定到由Switch切换的属性

时间:2018-11-16 10:30:36

标签: xaml xamarin.forms

我有一个Switch绑定到List中某个元素的属性。我想将按钮的IsVisible绑定到相同的属性,但是当通过Switch更改属性时,按钮的可见性不会改变。我想念什么?

XAML:

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

ViewModel:

private Command<Equipment> _doCommand;
    public Command<Equipment> DoCommand => _doCommand ??
(_doCommand = new Command<Equipment>((Equipment obj) => HandleEquipment(obj)));


// Outputs correct Name and State of the list item
private void HandleEquipment(Equipment obj)
{
        System.Diagnostics.Debug.WriteLine(obj.Name + ", " + obj.State);
}

型号:

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;
    }
}

2 个答案:

答案 0 :(得分:1)

正如Gerald在他的第一句话中写道:您必须在INotifyPropertyChanged模型上(而不只是在ViewModel中)实现Equipment接口。

没有此实现,视图中的元素就没有机会知道状态已更改(在您的情况下为按钮)。

实施:

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属性可以识别更改并更新其值。

答案 1 :(得分:0)

为什么不将两个东西绑定到一个属性,为什么不绑定单个项目(即开关)并使用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所在的窗口,但是如果将BooleanToVisibilityConverter放置在“资源”部分中,则可以在XAML文件中使用它。 这意味着如果将来更改属性名称,则只需在用户界面中只有一个位置需要更新,并且您还将使用XAML语言的功能。

正如每个人正确指出的那样,您还需要在模型中实现INotifyPropertyChanged,以便也可以更新Switch。