Tentukan HubSection yang dipilih di Hub dengan dua HubSections

Saya memiliki kontrol hub dengan dua HubSections. Ketika HubSection yang dipilih berubah, saya ingin mengubah konten AppBar dengan tombol khusus bagian.

Mendengarkan peristiwa SectionsInViewChanged adalah solusi umum yang direkomendasikan untuk mengimplementasikan perilaku ini tetapi peristiwa ini tidak dipicu ketika hanya ada dua HubSections.

Apakah ada event lain yang bisa digunakan untuk menentukan HubSection saat ini?

Terima kasih.


person Birkan Cilingir    schedule 18.01.2015    source sumber
comment
Sudahkah Anda membaca komentar jawaban ini (khususnya komentar Jerry Nixon)? Ada kalanya lebih dari satu bagian hub terlihat di halaman, jadi bagian hub mana yang utama? (Letakkan ponsel Anda dalam mode lanskap untuk memahami maksud saya.) Mungkin Anda bisa menggunakan kontrol Pivot saja?   -  person Decade Moon    schedule 19.01.2015
comment
Mungkin menguji solusi ini visuallylocationd.com/post/2014/08/26/ tidak yakin ini memperbaiki masalah 2 bagian   -  person Depechie    schedule 19.01.2015
comment
@Depechie meskipun masalah yang muncul ketika hanya ada dua bagian yang ditargetkan dalam artikel anehnya tidak menyelesaikan masalah. Tapi saya mungkin menggunakan ini dalam kombinasi dengan HorizontalOffset dari ScrollViewer untuk memutuskan apakah ini ada di bagian pertama atau kedua. Terima kasih untuk tautannya.   -  person Birkan Cilingir    schedule 23.01.2015
comment
@DecadeMoon ya saya sudah membaca jawaban itu tetapi saya akan menggunakan perilaku ini dalam kasus khusus jadi menurut saya itu tidak akan menimbulkan masalah.   -  person Birkan Cilingir    schedule 23.01.2015


Jawaban (2)


@Depechie telah mengarahkan Anda ke arah yang benar.. Anda dapat menggunakan Kontrol SelectionHub Saya membuat dan menambahkan acara ke dalamnya yang diaktifkan ketika indeks yang dipilih berubah

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

Anda dapat memperluas ini dengan menambahkan argumen peristiwa pilihan yang diubah ke dalamnya. Dengan ini Anda kemudian dapat berlangganan acara dalam kode Anda di belakang dan mengubah tombol bilah aplikasi berdasarkan indeks.

person Shawn Kendrot    schedule 23.01.2015
comment
Saya telah menggunakan solusi perilaku dalam sampel Anda. Peristiwa ini terjadi secara normal tetapi hub.Sections.IndexOf(hub.SectionsInView[0]) selalu mengembalikan nol (bagian pertama) ketika hanya ada dua bagian di hub. Apakah saya melewatkan sesuatu? Saya yakin saya dapat menggunakan HorizontalOffsetproperty dari ScrollViewer untuk memutuskan bagian mana yang memiliki bagian lebih besar dalam tampilan, tetapi saya tidak yakin apakah itu merupakan solusi rawan kesalahan. Ngomong-ngomong, terima kasih atas artikelnya. - person Birkan Cilingir; 25.01.2015
comment
Di akhir metode ScrollerOnViewChanged solusi di artikel Anda, saya memeriksa apakah scrollViewer.HorizontalOffset > (scrollViewer.ViewportWidth / 2) dan memutuskan bagian mana yang memiliki bagian lebih besar dalam tampilan. Saya ingin menulis bagian yang saya gunakan dari solusi Anda sebagai jawaban jika Anda setuju. - person Birkan Cilingir; 25.01.2015
comment
Acara ini akan diaktifkan berkali-kali dan pada akhirnya akan menyebutkan indeks hub dengan kode yang diberikan. - person Shawn Kendrot; 27.01.2015
comment
Sayangnya cara kerjanya berbeda saat saya menjalankannya. Jika ada lebih dari dua bagian, ScrollerOnViewChanged acara diaktifkan beberapa kali seperti yang Anda sarankan dan pada akhirnya indeksnya adalah yang benar. Jika saya menghapus bagian dan hanya menyisakan Bagian Satu dan Bagian Dua, acara tersebut dipicu beberapa kali lagi tetapi kali ini indeks selalu nol. Saat kita memeriksa properti hub.SectionsInView[0] dan bagian yang terlihat tidak berubah, bukankah ini perilaku normal? - person Birkan Cilingir; 29.01.2015

Setelah membaca Artikel Shawn disarankan oleh @Depechie. Saya mencoba menerapkan solusi yang sama di aplikasi saya untuk memperbarui konten AppBar dengan tombol khusus bagian.

Meskipun saya sudah berusaha, saya tidak dapat membuatnya berhasil jadi saya memodifikasi beberapa bagian solusinya. Saya menggunakan solusi perilaku dan hanya mengubah ScrollerOnViewChangedfungsi sebagai berikut. Ini mungkin bukan cara terbaik atau mungkin menyebabkan hasil yang tidak diharapkan dalam skenario yang berbeda, tetapi dalam kasus saya ini berhasil tanpa masalah.

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

Setelah itu saya menambahkan properti ke model tampilan saya untuk menyimpan indeks yang dipilih.

    private int _selectedIndex;

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

Saya menggunakan perilaku di XAML untuk memperbarui SelectedIndex di ViewModel saya.

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

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

Hal terakhir yang harus dilakukan adalah mengatur visibilitas AppBarButtons menggunakan properti ini. SectionIndexToVisibilityConverter membandingkan SelectedIndex dengan ConverterParameter dan mengembalikan Visibility.Visible jika sama.

<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>

Terima kasih @Depechie telah menyarankan artikelnya dan @Shawn telah menulis artikelnya :)

person Birkan Cilingir    schedule 05.02.2015