确定具有两个 HubSection 的 Hub 中选定的 HubSection

Determine the selected HubSection in a Hub with two HubSections

我有一个带有两个 HubSection 的集线器控件。 When selected HubSection changes, I want to change the contents of the AppBar with section specific buttons.

侦听 SectionsInViewChanged 事件是建议实现此行为的一般解决方案,但当只有两个 HubSection 时不会触发此事件。

是否有其他事件可用于确定当前的 HubSection?

谢谢。

@Depechie 为您指明了正确的方向。您可以使用我创建的 SelectionHub control 并向其添加一个事件,该事件会在所选索引更改时触发

public event EventHandler SelectionChanged;

private static void OnSelectedIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var hub = d as SelectionHub;
    if (hub == null) return;

    // do not try to set the section when the user is swiping
    if (hub._settingIndex) return;

    // No sections?!?
    if (hub.Sections.Count == 0) return;
    hub.OnSelectionChanged();
}

private void OnSelectionChanged()
{
    var section = Sections[SelectedIndex];
    ScrollToSection(section);
    var handler = SelectionChanged;
    if(handler != null)
    {
        handler(this, EventArgs.Empty);
    }
}

您可以通过向其添加选择更改事件参数来扩展它。有了这个,你就可以在你的代码后面订阅事件,并根据索引更改应用栏按钮。

阅读了@Depechie 建议的Shawn's article。我试图在我的应用程序中实施相同的解决方案,以便使用特定于部分的按钮更新 AppBar 的内容。

尽管我付出了很多努力,但还是无法让它发挥作用,所以我修改了解决方案的某些部分。我使用了行为解决方案并仅更改了 ScrollerOnViewChanged 函数,如下所示。这可能不是最好的方法,或者可能会在不同的情况下导致意外的结果,但在我的情况下它没有问题。

    private void ScrollerOnViewChanged(object sender, ScrollViewerViewChangedEventArgs scrollViewerViewChangedEventArgs)
    {
        _settingIndex = true;
        ScrollViewer scrollViewer = sender as ScrollViewer;
        if (scrollViewer.HorizontalOffset > (scrollViewer.ViewportWidth / 2))
            SelectedIndex = 1;
        else
            SelectedIndex = 0;

        _settingIndex = false;
    }

之后,我向我的视图模型添加了一个 属性 以存储选定的索引。

    private int _selectedIndex;

    public int SelectedIndex
    {
        get { return _selectedIndex; }
        set
        {
            SetProperty(ref this._selectedIndex, value);
        }
    }

我使用 XAML 中的行为来更新我的 ViewModel 中的 SelectedIndex。

<Hub>
    <i:Interaction.Behaviors>
        <behaviors:HubSelectionBehavior SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}" />
    </i:Interaction.Behaviors>

    <HubSection>...</HubSection>
    <HubSection>...</HubSection>
</Hub>

最后要做的是使用这个 属性 设置 AppBarButtons 的可见性。 SectionIndexToVisibilityConverter 将 SelectedIndex 与 ConverterParameter 进行比较,如果它们相等,则 returns Visibility.Visible

<CommandBar>
    <AppBarButton Label="Open" Icon="World" Command="{Binding OpenInBrowserCommand}" Visibility="{Binding SelectedIndex, Converter={StaticResource SectionIndexToVisibilityConverter}, ConverterParameter=0}"/>

    <AppBarButton Label="Previous" Icon="Back" Command="{Binding PreviousAnswerCommand}" Visibility="{Binding SelectedIndex, Converter={StaticResource SectionIndexToVisibilityConverter}, ConverterParameter=1}"/>
    <AppBarButton Label="Next" Icon="Forward" Command="{Binding NextAnswerCommand}" Visibility="{Binding SelectedIndex, Converter={StaticResource SectionIndexToVisibilityConverter}, ConverterParameter=1}"/>
</CommandBar>

感谢@Depechie 推荐文章和@Shawn 撰写文章:)