我正在尝试使用 ToggleMenuFlyoutItems 创建一个 MenuFlyout,其中在任何给定时刻仅检查一个切换。切换对应于 ToggleViewModels,将切换的 IsChecked 属性绑定到 ToggleViewModel 的 IsSelected 属性。因为我想在选中新切换时取消选中之前选中的切换,所以我将 IsSelected 属性的设置传递给包含 ToggleViewModel 集合的 MainViewModel。
在 MainPage.xaml 中定义的带有弹出按钮的按钮
<Button Content="Asdf">
<Button.Flyout>
<MenuFlyout>
<ToggleMenuFlyoutItem
Text="{x:Bind _viewModel.ToggleCollection[0].Name}"
IsChecked="{x:Bind _viewModel.ToggleCollection[0].IsSelected, Mode=TwoWay}" />
<ToggleMenuFlyoutItem
Text="{x:Bind _viewModel.ToggleCollection[1].Name}"
IsChecked="{x:Bind _viewModel.ToggleCollection[1].IsSelected, Mode=TwoWay}" />
<ToggleMenuFlyoutItem
Text="{x:Bind _viewModel.ToggleCollection[2].Name}"
IsChecked="{x:Bind _viewModel.ToggleCollection[2].IsSelected, Mode=TwoWay}" />
</MenuFlyout>
</Button.Flyout>
</Button>
主页面视图模型:
public class MainViewModel : BindableBase
{
public MainViewModel()
{
ToggleCollection = new ObservableCollection<ToggleViewModel>();
var selectToggleAction = new Action<ToggleViewModel>(param => SetToggleSelection(param));
for (int i = 0; i < 3; i++)
{
ToggleCollection.Add(new ToggleViewModel($"Item {i}", selectToggleAction));
}
}
public ObservableCollection<ToggleViewModel> ToggleCollection { get; private set; }
private void SetToggleSelection(ToggleViewModel toggle)
{
var selectedToggle = ToggleCollection.SingleOrDefault(t => t.IsSelected);
if (selectedToggle != toggle)
{
selectedToggle?.SetSelection(false);
toggle.SetSelection(true);
}
}
}
切换视图模型:
public class ToggleViewModel : BindableBase
{
private Action<ToggleViewModel> _selectToggleAction;
private bool _isSelected;
public ToggleViewModel(string name, Action<ToggleViewModel> action)
{
Name = name;
_selectToggleAction = action;
}
public string Name { get; set; }
public bool IsSelected
{
get { return _isSelected; }
set
{
if (_isSelected != value)
{
_selectToggleAction(this);
base.OnPropertyChanged();
}
}
}
public void SetSelection(bool selected)
{
_isSelected = selected;
base.OnPropertyChanged("IsSelected");
}
}
现在上面的所有代码都运行良好。当我尝试使用常规绑定而不是编译绑定时会出现问题:
<ToggleMenuFlyoutItem
Text="{Binding ToggleCollection[0].Name}"
IsChecked="{Binding ToggleCollection[0].IsSelected, Mode=TwoWay}" />
像这样绑定属性我突然能够取消选中当前选中的切换,以便没有选择任何一个。这是由于当我在 IsSelected 属性的 setter 中引发 OnPropertyChanged 时未调用 IsSelected 属性的 getter(使用常规绑定的原因是我想在后面的代码中动态创建切换,但为了说明问题XAML 也同样有效)。
谁能向我解释为什么{x:Bind}
在这种情况下有效但不是{Binding}
?