【问题标题】:How to replace detail pane with specific pages in MasterDetailsView on master item click如何在主项目单击时用 MasterDetailsView 中的特定页面替换详细信息窗格
【发布时间】:2020-07-16 15:11:08
【问题描述】:

每当用户单击主窗格中的项目时,如何在详细信息窗格中显示特定页面?我在详细信息窗格中创建了一个框架,以便更轻松高效地加载页面,但我不知道从单击事件执行此操作或在项目类中指定页面名称并从那里读取值是否更有效。

目标页面:页面 A、页面 B、页面 C、页面 D

MainPage.xaml

<Page.Resources>
    <converters:BoolToVisibilityConverter x:Key="MyConveter" />
</Page.Resources>
<Grid x:Name="RootGrid">
    <controls:MasterDetailsView
        x:Name="MyMasterDetailsView"
        BackButtonBehavior="Automatic"
        CompactModeThresholdWidth="720"
        ItemsSource="{x:Bind Emails}"
        NoSelectionContent="Select an item to view"
        >
        <controls:MasterDetailsView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>

                    <StackPanel Grid.Column="0" Margin="0,8">
                        <TextBlock 
                            Style="{ThemeResource SubtitleTextBlockStyle}" 
                            Text="{Binding From}" />
                        <TextBlock
                            Opacity=".6"
                            Style="{ThemeResource BodyTextBlockStyle}"
                            Text="{Binding Body}"
                            />
                    </StackPanel>

                    <Button
                        x:Name="MoreBtn"
                        Grid.Column="1"
                        Margin="10"
                        Padding="10"
                        HorizontalAlignment="Right"
                        VerticalAlignment="Top"
                        Background="Transparent"
                        Click="MoreBtn_Click"
                        Command="{Binding ElementName=RootGrid, Path=DataContext.OpenDialog}"
                        CommandParameter="{Binding}"
                        Content="&#xE712;"
                        FontFamily="Segoe MDL2 Assets"
                        Visibility="{Binding ShowButton, Converter={StaticResource MyConveter}}"
                        />
                </Grid>
            </DataTemplate>
        </controls:MasterDetailsView.ItemTemplate>
        <controls:MasterDetailsView.DetailsTemplate>
            <DataTemplate>
                <Frame x:Name="DetailFrame"/>
            </DataTemplate>
        </controls:MasterDetailsView.DetailsTemplate>
        <controls:MasterDetailsView.NoSelectionContentTemplate>
            <DataTemplate>
                <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                    <SymbolIcon RenderTransformOrigin=".5,.5" Symbol="Mail">
                        <SymbolIcon.RenderTransform>
                            <CompositeTransform ScaleX="2" ScaleY="2" />
                        </SymbolIcon.RenderTransform>
                    </SymbolIcon>
                    <TextBlock
                        Margin="0,12"
                        FontSize="24"
                        Text="{Binding}"
                        />
                </StackPanel>
            </DataTemplate>
        </controls:MasterDetailsView.NoSelectionContentTemplate>
        <controls:MasterDetailsView.MasterCommandBar>
            <CommandBar>
                <AppBarButton Icon="Back" Label="Back" />
                <AppBarButton Icon="Forward" Label="Forward" />

                <CommandBar.Content>
                    <TextBlock Margin="12,14">
                        <Run Text="{Binding Emails.Count}" />
                        <Run Text="Items" />
                    </TextBlock>
                </CommandBar.Content>
            </CommandBar>
        </controls:MasterDetailsView.MasterCommandBar>
        <controls:MasterDetailsView.DetailsCommandBar>
            <CommandBar>
                <AppBarButton Icon="MailReply" Label="Reply" />
                <AppBarButton Icon="MailReplyAll" Label="Reply All" />
                <AppBarButton Icon="MailForward" Label="Forward" />
            </CommandBar>
        </controls:MasterDetailsView.DetailsCommandBar>
    </controls:MasterDetailsView>
</Grid>

MainPage.xaml.cs

 public sealed partial class MainPage : Page
    {
        public List<Email> Emails { get; set; }
        public MainPage()
        {
            this.InitializeComponent();
            this.DataContext = this;
            Emails = MyEmailManager.GetEmails();
        }
        public ICommand OpenDialog
        {
            get
            {
                return new CommadEventHandler<Email>((s) => OpenDialogCommandFun(s));
            }
        }
        private async void OpenDialogCommandFun(Email s)
        {
            ContentDialog dialogServiceUpdates = new ContentDialog
            {
                Title = s.From,
                Content = s.Body,
                CloseButtonText = "OK"
            };

            ContentDialogResult result = await dialogServiceUpdates.ShowAsync();
        }
        private void MoreBtn_Click(object sender, RoutedEventArgs e)
        {

        }
    }

    public class Email
    {
        public string From { get; set; }
        public string Body { get; set; }
        public bool ShowButton { get; set; }
    }

    public class MyEmailManager
    {
        public static List<Email> GetEmails()
        {
            var MyEmails = new List<Email>
        {
            new Email
            {
                From = "Steve Johnson",
                Body = "Are you available for lunch tomorrow? A client would like to discuss a project with you.",
                ShowButton = true
            },
            new Email
            {
                From = "Pete Davidson",
                Body = "Don't forget the kids have their soccer game this Friday. We have to supply end of game snacks.",
                ShowButton = false
            },
            new Email
            {
                From = "OneDrive",
                Body = "Your new album.\r\nYou uploaded some photos to your OneDrive and automatically created an album for you.",
                ShowButton = false
            },
            new Email
            {
                From = "Twitter",
                Body = "Here are some people we think you might like to follow:\r\n.@randomPerson\r\nAPersonYouMightKnow",
                ShowButton = true
            }
        };

            return MyEmails;
        }
    }

    public class CommadEventHandler<T> : ICommand
    {
        public event EventHandler CanExecuteChanged;

        public Action<T> action;
        public bool CanExecute(object parameter)
        {
            return true;
        }

        public void Execute(object parameter)
        {
            this.action((T)parameter);
        }
        public CommadEventHandler(Action<T> action)
        {
            this.action = action;

        }
    }

预期结果

【问题讨论】:

标签: c# xaml uwp windows-10 uwp-xaml


【解决方案1】:

我建议你参考我以前的replyFrame 具有 SourcePageType 属性,用于绑定 mvvm 模型中的特定页面类型。所以你可以将Frame 插入DetailsTemplate。并与模型From 属性绑定,然后使用转换器返回匹配的页面类型。

示例代码。

<Page.Resources>
    <converters:BoolToVisibilityConverter x:Key="MyConveter" />
    <local:PageConverter x:Name="PageConverter" />
</Page.Resources>

......

<controls:MasterDetailsView.DetailsTemplate>
    <DataTemplate>
        <RelativePanel Margin="24">
            <TextBlock
                Margin="12,-6,0,0"
                Style="{ThemeResource SubtitleTextBlockStyle}"
                Text="{Binding From}"
                />
            <TextBlock
                x:Name="Body"
                Margin="0,12,0,0"
                Style="{ThemeResource BodyTextBlockStyle}"
                Text="{Binding Body}"
                TextWrapping="Wrap"
                />
            <Frame
                Margin="0,100,0,0"
                RelativePanel.AlignBottomWithPanel="True"
                RelativePanel.AlignHorizontalCenterWithPanel="True"
                RelativePanel.AlignLeftWithPanel="True"
                RelativePanel.AlignRightWithPanel="True"
                RelativePanel.AlignTopWithPanel="True"
                SourcePageType="{Binding From, Converter={StaticResource PageConverter}, Mode=TwoWay}"
                />
        </RelativePanel>
    </DataTemplate>
</controls:MasterDetailsView.DetailsTemplate>

转换器

public class PageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        Type page = null;
        switch (value as string)
        {
            case "Steve Johnson":
                page = typeof(FistPage);
                break;
            case "Pete Davidson":
                page = typeof(SecondPage);
                break;
            case "OneDrive":
                page = typeof(FistPage);
                break;
            case "Twitter":
                page = typeof(SecondPage);
                break;
            default:
                break;
        }

        return page;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

这里是代码sample

【讨论】:

  • GridView 的点击事件呢?以下代码对我不起作用,因为我之前使用的是单独的类。 private async void GridView_ItemClick(object sender, ItemClickEventArgs e) { var item = MyGridView.ContainerFromItem(e.ClickedItem) as GridViewItem; if (item.Title == "System") { } }
  • 我已经在 QA 中回复了您的相同主题,请检查。
  • 如何使用字符串资源?而不是case "Steve Johnson" 我想使用case resourceLoader.GetString("SteveJohnson/Text")
  • 嗨@MacaronLover,请避免在cmets中发布新问题,请创建新线程并分享链接。
猜你喜欢
  • 2020-04-19
  • 2019-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多