Windows-XAML / Template10

Making Windows 10 apps great again
Apache License 2.0
1.41k stars 390 forks source link

Master/Details: Details view not updated when selecting a new item #839

Closed Gh0s7 closed 8 years ago

Gh0s7 commented 8 years ago

Starting from the sample I've edited the Master/Details code to build a settigns page. However the Details part is not updated when I select a new item, and I can't understand what's going on. Basically just the first selection works, for the others the Master view is updated but it keeps on loading the first Detail selected.

Here's some code, hoping that someone can help me.

M/D

<controls:MasterDetailsView RelativePanel.AlignBottomWithPanel="True"
                                    RelativePanel.AlignLeftWithPanel="True"
                                    RelativePanel.AlignRightWithPanel="True"
                                    RelativePanel.Below="PageHeader"
                                    x:Name="MasterDetailsView"                                    
                                    Details="{Binding SelectedSetting, Mode=OneWay}"
                                    ItemsSource="{Binding SettingsCategories, Mode=OneWay}"
                                    SelectedItem="{Binding SelectedSetting, Mode=TwoWay}"
                                    DetailsTemplate="{StaticResource SettingDetailDataTemplate}"
                                    ItemTemplate="{StaticResource SettingsItemDataTemplate}">

            <controls:MasterDetailsView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" 
                            Value="Stretch" />
                    <Setter Property="Padding" Value="0" />
                </Style>
            </controls:MasterDetailsView.ItemContainerStyle>
        </controls:MasterDetailsView>

Styles

<DataTemplate x:Key="SettingsItemDataTemplate">
        <StackPanel Orientation="Horizontal">
            <SymbolIcon Symbol="{Binding SettingIcon}"
                                    Width="48"
                                    Height="48"
                                    Foreground="{ThemeResource SystemControlForegroundAccentBrush}" />
            <TextBlock Text="{Binding SettingName}"
                                   VerticalAlignment="Center"
                                   LineStackingStrategy="BaselineToBaseline"
                                   Margin="0,-5,0,0"
                                   Style="{ThemeResource TitleTextBlockStyle}" />
        </StackPanel>
    </DataTemplate>

    <DataTemplate x:Key="SettingDetailDataTemplate">
        <Frame SourcePageType="{Binding SettingType}" />
    </DataTemplate>

    <Style TargetType="controls:MasterDetailsView">
        <Setter Property="HorizontalAlignment" Value="Stretch" />
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        <Setter Property="VerticalAlignment" Value="Stretch" />
        <Setter Property="VerticalContentAlignment" Value="Stretch" />
        <Setter Property="IsItemClickEnabled" Value="True" />
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="TabNavigation" Value="Once" />
        <Setter Property="IsSwipeEnabled" Value="True" />
        <Setter Property="VisualStateNarrowMinWidth" Value="0" />
        <Setter Property="VisualStateNormalMinWidth" Value="521" />
        <Setter Property="MasterPaneWidth" Value="250" />
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
        <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
        <Setter Property="ScrollViewer.IsHorizontalRailEnabled" Value="False" />
        <Setter Property="ScrollViewer.VerticalScrollMode" Value="Enabled" />
        <Setter Property="ScrollViewer.IsVerticalRailEnabled" Value="True" />
        <Setter Property="ScrollViewer.ZoomMode" Value="Disabled" />
        <Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False" />
        <Setter Property="ScrollViewer.BringIntoViewOnFocusChange" Value="True" />
        <Setter Property="ItemContainerTransitions">
            <Setter.Value>
                <TransitionCollection>
                    <AddDeleteThemeTransition />
                    <ContentThemeTransition />
                    <ReorderThemeTransition />
                    <EntranceThemeTransition IsStaggeringEnabled="False" />
                </TransitionCollection>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <ItemsStackPanel Orientation="Vertical" />
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="controls:MasterDetailsView">
                    <Border
                        x:Name="ControlRoot"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition x:Name="MasterPane"
                                                  Width="{Binding MasterPaneWidth, RelativeSource={RelativeSource TemplatedParent}}" />
                                <ColumnDefinition x:Name="SeparatorPane" Width="5"/>
                                <ColumnDefinition x:Name="DetailsPane" Width="*" />
                            </Grid.ColumnDefinitions>
                            <Grid x:Name="DetailsGrid"
                                  Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
                                  Padding="10,5"
                                  Grid.Column="2">
                                <ProgressRing
                                    x:Name="DetailsProgressRing"
                                    Width="40"
                                    Height="40"
                                    IsActive="True"
                                    Visibility="Collapsed" />
                                <ContentControl
                                    x:Name="ContentControl"
                                    HorizontalAlignment="Stretch"
                                    VerticalAlignment="Stretch"
                                    HorizontalContentAlignment="Stretch"
                                    VerticalContentAlignment="Stretch"
                                    Content="{TemplateBinding Details}"
                                    ContentTemplate="{TemplateBinding DetailsTemplate}"
                                    IsTabStop="False" />
                            </Grid>
                            <Grid x:Name="SeparatorGrid"
                                  Grid.Column="1"/>
                            <Grid x:Name="MasterGrid"
                                  Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
                                  Grid.Column="0">
                                <ProgressBar x:Name="MasterProgressBar"
                                             Margin="0,2,0,0"
                                             HorizontalAlignment="Stretch"
                                             VerticalAlignment="Top"
                                             IsIndeterminate="True"
                                             Visibility="Collapsed" />
                                <ScrollViewer x:Name="ScrollViewer"
                                              AutomationProperties.AccessibilityView="Raw"
                                              BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}"
                                              HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
                                              HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
                                              IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
                                              IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
                                              IsHorizontalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsHorizontalScrollChainingEnabled}"
                                              IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
                                              IsVerticalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsVerticalScrollChainingEnabled}"
                                              TabNavigation="{TemplateBinding TabNavigation}"
                                              VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
                                              VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
                                              ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}">
                                    <ItemsPresenter Padding="{TemplateBinding Padding}"
                                                    Footer="{TemplateBinding Footer}"
                                                    FooterTemplate="{TemplateBinding FooterTemplate}"
                                                    FooterTransitions="{TemplateBinding FooterTransitions}"
                                                    Header="{TemplateBinding Header}"
                                                    HeaderTemplate="{TemplateBinding HeaderTemplate}"
                                                    HeaderTransitions="{TemplateBinding HeaderTransitions}" />
                                </ScrollViewer>
                            </Grid>
                        </Grid>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="NarrowVisualStateGroup">
                                <VisualState x:Name="DetailsVisualState">
                                    <VisualState.Setters>
                                        <Setter Target="MasterPane.Width" Value="0" />
                                        <Setter Target="SeparatorPane.Width" Value="0" />
                                        <Setter Target="DetailsPane.Width" Value="*" />
                                    </VisualState.Setters>
                                </VisualState>
                                <VisualState x:Name="MasterVisualState">
                                    <VisualState.Setters>
                                        <Setter Target="MasterPane.Width" Value="*" />
                                        <Setter Target="SeparatorPane.Width" Value="0" />
                                        <Setter Target="DetailsPane.Width" Value="0" />
                                    </VisualState.Setters>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="AdaptiveVisualStateGroup">
                                <VisualState x:Name="VisualStateNarrow">
                                    <VisualState.StateTriggers>
                                        <AdaptiveTrigger
                                            MinWindowWidth="{Binding VisualStateNarrowMinWidth, RelativeSource={RelativeSource TemplatedParent}}" />
                                    </VisualState.StateTriggers>
                                    <VisualState.Setters>
                                        <Setter Target="MasterPane.Width" Value="*" />
                                        <Setter Target="DetailsPane.Width" Value="0" />
                                        <Setter Target="SeparatorPane.Width" Value="0" />
                                    </VisualState.Setters>
                                </VisualState>
                                <VisualState x:Name="VisualStateNormal">
                                    <VisualState.StateTriggers>
                                        <AdaptiveTrigger
                                            MinWindowWidth="{Binding VisualStateNormalMinWidth, RelativeSource={RelativeSource TemplatedParent}}" />
                                    </VisualState.StateTriggers>
                                    <VisualState.Setters>
                                        <Setter Target="MasterPane.Width"
                                                Value="{Binding MasterPaneWidth, RelativeSource={RelativeSource TemplatedParent}}" />
                                        <Setter Target="DetailsPane.Width" Value="*" />
                                        <Setter Target="SeparatorPane.Width" Value="5" />
                                    </VisualState.Setters>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="DeviceVisualStateGroup">
                                <VisualState x:Name="DesktopVisualState" />
                                <VisualState x:Name="MobileVisualState" />
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Model

public class Setting
    {
        public string SettingName { get; }
        public Symbol SettingIcon { get; }
        public Type SettingType { get; }

        public Setting(string settingName, Symbol settingIcon, Type settingType)
        {
            SettingName = settingName;
            SettingIcon = settingIcon;
            SettingType = settingType;
        }
    }

One of the pages

<Page
    x:Class="MyApp.Views.SettingsPages.AboutPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyApp.Views.SettingsPages"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:viewModels="using:MyApp.ViewModels"
    mc:Ignorable="d">

    <Page.DataContext>
        <viewModels:SettingsPageViewModel />
    </Page.DataContext>

    <RelativePanel>

        <Border x:Name="LogoImage"
                HorizontalAlignment="Right"
                VerticalAlignment="Top"
                BorderBrush="DimGray"
                BorderThickness="1"
                IsHitTestVisible="False"
                RelativePanel.AlignRightWithPanel="True"
                RelativePanel.AlignTopWithPanel="True">
            <Border.Background>
                <SolidColorBrush Color="{ThemeResource SystemAccentColor}" />
            </Border.Background>
            <Image Margin="12"
                   Source="{Binding Logo}"
                   Stretch="None" />
        </Border>

        <TextBlock x:Name="DisplayNameTextBlock" Margin="0,0,0,12"
                   FontSize="24" RelativePanel.AlignLeftWithPanel="True"
                   RelativePanel.AlignRightWith="LogoImage"
                   RelativePanel.AlignTopWithPanel="True"
                   Text="{Binding DisplayName}" />

        <TextBlock x:Name="PublisherTextBlock"
                   RelativePanel.AlignLeftWithPanel="True"
                   RelativePanel.Below="DisplayNameTextBlock"
                   Text="{Binding Publisher}" />

        <TextBlock x:Name="VersionTextBlock"
                   RelativePanel.AlignLeftWithPanel="True"
                   RelativePanel.Below="PublisherTextBlock">
            <Run Text="Version"
                 x:Uid="Version" />
            <Run Text="{Binding Version}" />
        </TextBlock>

    </RelativePanel>
</Page>

Part of SettingsPageViewModel

public ObservableCollection<Setting> SettingsCategories { get; } = new ObservableCollection<Setting>();
        private Setting _selectedSetting;
        public object SelectedSetting
        {
            get
            {
                return _selectedSetting;
            }
            set
            {
                Set(ref _selectedSetting, (Setting) value);
            }
        }

public SettingsPageViewModel()
        {
            _settings = SettingsService.Instance;
            SettingsCategories.Add(new Setting("Personalization", Symbol.Add, typeof (PersonalizationPage)));
            SettingsCategories.Add(new Setting("Security", Symbol.Permissions, typeof (SecurityPage)));
            SettingsCategories.Add(new Setting("Feedback", Symbol.Emoji2, typeof (FeedbackPage)));
            SettingsCategories.Add(new Setting("About", Symbol.Contact, typeof (AboutPage)));
            IsDetailsLoading = false;
        }

        public override Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary<string, object> state)
        {
            SelectedSetting = SettingsCategories[0];
            return Task.CompletedTask;
        }

Everytime the PersonalizationPage is loaded, even if the SelectedSetting is updated correctly (tried with a breakpoint). What am I doing wrong?

JerryNixon commented 8 years ago

Please ask this on Stack Overflow.