我有一个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;
}
}
答案 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。