Любопытная разница в поведении между скомпилированным и регулярным связыванием

Я пытаюсь создать MenuFlyout с ToggleMenuFlyoutItems, где один и только один переключатель проверяется в любой момент. Переключатели соответствуют ToggleViewModels, связывая свойство IsChecked переключателя со свойством IsSelected объекта ToggleViewModel. Поскольку я хочу снять флажок с ранее проверенного переключателя всякий раз, когда проверяется новый переключатель, я передаю настройку свойства IsSelected в MainViewModel, который содержит коллекцию ToggleViewModels.

Кнопка с выпадающим списком, определенным в 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>

MainPageViewModel:

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

ToggleViewModel:

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

Может кто-нибудь объяснить мне, почему {x:Bind} в этом случае работает, но не {Binding}?

0 ответов

Другие вопросы по тегам