Привязка IsVisible к свойству, переключаемому с помощью Switch - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть Switch, связанный со свойством элемента в List.Я хочу привязать IsVisible кнопки к тому же свойству, но видимость кнопки не изменяется при изменении свойства коммутатором.Чего мне не хватает?

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 голосов
/ 16 ноября 2018

Вместо того, чтобы связывать две вещи со свойством, почему бы не привязать один элемент (то есть переключатель) и использовать 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 в модели, чтобы коммутатор тоже обновлялся.

0 голосов
/ 16 ноября 2018

Как написал Джеральд в своем первом комментарии: Вы должны реализовать интерфейс INotifyPropertyChanged в своей модели 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 кнопки распознает изменение и обновляет его значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...