LoadFromXaml解析异常膨胀MenuBarItem

svujldwt  于 2022-12-16  发布在  其他
关注(0)|答案(2)|浏览(119)

当我尝试使用该方法膨胀我的XAML时:

MenuBarItem item = new().LoadFromXaml("<MenuBarItem Text=\"Session\"><MenuFlyoutItem Text=\"New\"/><MenuFlyoutItem Text=\"Save\"/><MenuFlyoutItem Text=\"Load\"/></MenuBarItem>");

创建MenuBarItem并正确分配文本,但忽略所有MenuFlyoutItem且不将其添加到菜单中。
在阅读Load XAML at runtime文档,特别是“LoadFromXaml方法可以用于膨胀任何XAML”和给出的示例之后,我假设我可以向其中抛入任何有效的XAML-从单个按钮到ListView的DataTemplate,菜单的MenuBarItem,到整个ContentPage,它应该工作。但在这种情况下,它不工作-我得到微软。毛伊岛。控件。Xaml。XamlParseException和System. Reflection. TargetInvocationException。
这个行为是一个错误还是文档缺少一些关于加载XAML的细节?
当我将MenuBarItem包含在ContentPage的MenuBarItem中时,如下所示:

new ContentPage().LoadFromXaml("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<ContentPage\r\n\txmlns=\"http://schemas.microsoft.com/dotnet/2021/maui\"\r\n\txmlns:x=\"http://schemas.microsoft.com/winfx/2009/xaml\"\r\n\tx:Class=\"LoadRuntimeXAML.CatalogItemsPage\"\r\n\tTitle=\"Catalog Items\">\r\n\t<ContentPage.MenuBarItems>\r\n\t\t<MenuBarItem Text=\"Session\">\r\n\t\t\t<MenuFlyoutItem\r\n\t\t\t\tText=\"New\"/>\r\n\t\t\t<MenuFlyoutItem\r\n\t\t\t\tText=\"Save\"/>\r\n\t\t\t<MenuFlyoutItem\r\n\t\t\t\tText=\"Load\"/>\r\n\t\t</MenuBarItem>\r\n\t</ContentPage.MenuBarItems>\r\n</ContentPage>");

它会毫无错误地膨胀,然后当我将膨胀后的ContentPage中的元素分配给MainPage的MenuBarItem时,它们会显示得很好。但这是一个丑陋的解决方案,因为我不需要整个ContentPage,只需要MenuBarItem。

7dl7o3gd

7dl7o3gd1#

您的XAML不完整,因此无法进行分析。
ContentPage所具有而XAML所缺少的是各种xmlns行,这些行指定XAML中使用的XML元素。
我还没有测试过,但请尝试将<MenuBarItem替换为

<MenuBarItem\r\n\txmlns=\"http://schemas.microsoft.com/dotnet/2021/maui\"\r\n\txmlns:x=\"http://schemas.microsoft.com/winfx/2009/xaml\"\r\n

根据需要进行调整。任何空格都可以用于显示\r\n的任何位置。
如果它不起作用,也前缀:<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n
但我相信这是可以选择的。
顺便说一句,任何可以在XAML中完成的事情都可以在C#. C# markup中完成。
C#是一种完整的计算语言,如果您要构建依赖于不同条件的UI,则通常可以比XAML更容易地创建动态UI。
C#中的一个方便的方法是定义“helper”方法,该方法可以使用您想要的任何参数,并创建特定的元素。您可以通过C#标记或父布局类的方法将该元素添加到给定的父元素中。
编写调用其他helper方法的helper方法很容易,根据您的规范构建整个布局也很容易,每一步都由您关心的参数控制。
在顶层,您可能会得到如下代码:

// use custom helper methods and methods of "Grid" class.
Grid grid = MyCreateGrid();
grid.Children.Add(MyCreateRowLabel(text), 1, 0);
grid.Children.Add(
    // OR use C# markup
    new StackLayout
    {
      Children =
      {
        new Label().Text("Code:"),
        ...
      }
    },
    1, 1
);
...
slhcrj9b

slhcrj9b2#

从官方文档来看,LoadFromXaml只用于单视图或完整的contentPage,我也尝试过LoadFromXaml用于<MenuBarItem Text=\"Session\"><MenuFlyoutItem Text=\"New\"/><MenuFlyoutItem Text=\"Save\"/><MenuFlyoutItem Text=\"Load\"/></MenuBarItem>,刚才您说:
创建MenuBarItem并正确分配文本,但忽略所有MenuFlyoutItem且不将其添加到菜单中。
但你可以通过这样做来实现它:
MainPage.xaml:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp_loadXaml.MainPage"
             x:Name="contentPage">

   <Button Text="click" Clicked="Button_Clicked" HeightRequest="50"/>

</ContentPage>

MainPage.xaml.cs:

private void Button_Clicked(object sender, EventArgs e)
    {
        var xaml = "<MenuBarItem Text=\"Session\"></MenuBarItem>";
        var xaml1 = "<MenuFlyoutItem Text=\"New\"/>";
        var xaml2 = "<MenuFlyoutItem Text=\"Save\"/>";
        var xaml3 = "<MenuFlyoutItem Text=\"Load\"/>";

        MenuFlyoutItem menuFlyoutItem_1 = new MenuFlyoutItem().LoadFromXaml(xaml1);
        MenuFlyoutItem menuFlyoutItem_2 = new MenuFlyoutItem().LoadFromXaml(xaml2);
        MenuFlyoutItem menuFlyoutItem_3 = new MenuFlyoutItem().LoadFromXaml(xaml3);
        MenuBarItem item = new MenuBarItem();
        item.LoadFromXaml(xaml);

        item.Add(menuFlyoutItem_1);
        item.Add(menuFlyoutItem_2);
        item.Add(menuFlyoutItem_3);

       contentPage.MenuBarItems.Add(item);
    }

效果很好。

相关问题