c# - UWP 将 child 转移到其他 parent 问题

标签 c# xaml uwp parent-child uwp-xaml

首先,我是 UWP 的新手,我已经在几乎所有地方(使用 Google 和 Stackoverflow)搜索了答案,但找不到我的问题的答案。

那么问题来了:

我计划使用 Visual Studio 2017 和 Target Sdk:Creators Update 为 UWP 创建一个具有选项卡功能的像素绘画应用程序,例如 Edge(利用标题栏)。

当应用程序处于全屏状态时,我想将我制作的自定义标题栏移动到内容 View 。

我想从这里移动(windows 标题栏,这只是按钮 XAML 代码,我不包括选项卡栏 XAML 代码,因为它是一个商业项目):

<Grid x:Name="btnMenuPlace1" Grid.Column="0">
    <Grid x:Name="btnMenuPlaceContent" Background="{StaticResource SystemControlHighlightListAccentMediumBrush}">
    <Button x:Name="btnMenu" FontFamily="Segoe MDL2 Assets" Content="&#xE700;"
Width="50" Height="50" Background="Transparent" Click="btnMenu_Click"/>
    </Grid>
</Grid>

到这里(用户 View ):

<Grid x:Name="btnMenuPlace2" Grid.Column="0">
</Grid>

这些 Grid 的两个父级都是使用 Grid.ColumnDefinitions 的另一个 Grid,如下所示:

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto"/>
    <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

这是我的 C# 代码:

private void WindowSizeChanged(object sender, WindowSizeChangedEventArgs e)
{
    var appView = ApplicationView.GetForCurrentView();
    if (appView.IsFullScreenMode)
    {
        Utility.RemoveChild(btnMenuPlaceContent);
        btnMenuPlace2.Children.Add(btnMenuPlaceContent);
        Utility.RemoveChild(tabBarPlaceContent);
        tabBarPlace2.Children.Add(tabBarPlaceContent);
    }
    else
    {
        Utility.RemoveChild(btnMenuPlaceContent);
        btnMenuPlace1.Children.Add(btnMenuPlaceContent);
        Utility.RemoveChild(tabBarPlaceContent);
        tabBarPlace1.Children.Add(tabBarPlaceContent);
    }
    e.Handled = true;
}

这是我的实用程序 RemoveChild 代码:

public static void RemoveChild(DependencyObject parent, UIElement child)
{
    var parentAsPanel = VisualTreeHelper.GetParent(child);
    if (parentAsPanel != null)
    {
        parentAsPanel.Children.Remove(child);
        return;
    }
    var parentAsContentPresenter = parent as ContentPresenter;
    if (parentAsContentPresenter != null)
    {
        if (parentAsContentPresenter.Content == child)
        {
            parentAsContentPresenter.Content = null;
        }
        return;
    }
    var parentAsContentControl = parent as ContentControl;
    if (parentAsContentControl != null)
    {
        if (parentAsContentControl.Content == child)
        {
            parentAsContentControl.Content = null;
        }
        return;
    }
}

这是我的应用在进入全屏模式之前的样子:

Screenshoot of My App

所以问题是每当应用程序进入全屏模式时, child 确实移动到新的 parent ,但按钮不在那里,只有网格的背景颜色剩余,我无法点击它们中的任何一个(不是单击事件工作),看看:

Screenshoot of My App On Fullscreen

当我切换回非全屏 View 时,未显示新选项卡上的进度条加载。 我不知道我做错了 XAML 还是 C# 代码。

如有任何帮助,我们将不胜感激。

P.S.我是印度尼西亚人,所以我的句子可能有问题,希望您能理解我在说什么。

最佳答案

您的代码片段有问题。例如,RemoveChild 方法有两个参数,但您只在调用它时提供一个参数。如果不分配 parentAsPanel 变量类型,您将无法获得 Children 属性。

由于代码未完成,更新代码并添加一些其他需要的代码后,我可以正确运行您的代码片段,无法重现上述问题。这是我完成的测试代码:

XAML

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel>
        <Grid x:Name="btnMenuPlace1" Grid.Column="0" Grid.Row="0">
            <Grid x:Name="btnMenuPlaceContent" Background="{StaticResource SystemControlHighlightListAccentMediumBrush}">
                <StackPanel Orientation="Horizontal">
                    <Button x:Name="btnMenu" FontFamily="Segoe MDL2 Assets" Content="&#xE700;" Width="50" Height="50" Background="Transparent"  />
                    <!--<local:CustomTitleBar Width="200" Height="50"></local:CustomTitleBar>-->
                </StackPanel>
            </Grid>
        </Grid>
        <Grid x:Name="btnMenuPlace2" Grid.Column="1" Grid.Row="1"/>
        <TextBlock Text="text" x:Name="txtresult"></TextBlock>
        <Button x:Name="ToggleFullScreenModeButton" Margin="0,10,0,0" Click="ToggleFullScreenModeButton_Click">
            <SymbolIcon x:Name="ToggleFullScreenModeSymbol" Symbol="FullScreen" />
        </Button>
    </StackPanel> 
</Grid>

代码隐藏

public sealed partial class MainPage : Page
{
   public MainPage()
   {
       this.InitializeComponent();
       CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
       Window.Current.SetTitleBar(btnMenuPlace1);
       Window.Current.SizeChanged += Current_SizeChanged;
   }

   private void Current_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
   {
       var appView = ApplicationView.GetForCurrentView();
       if (appView.IsFullScreenMode)
       { 
           RemoveChild(btnMenuPlace1, btnMenuPlaceContent);
           btnMenuPlace2.Children.Add(btnMenuPlaceContent);            
       }
       else
       {
           RemoveChild(btnMenuPlace2, btnMenuPlaceContent);             
           btnMenuPlace1.Children.Add(btnMenuPlaceContent);
       }
       e.Handled = true;
   }

   public void RemoveChild(DependencyObject parent, UIElement child)
   {
       Grid parentAsPanel = VisualTreeHelper.GetParent(child) as Grid;
       if (parentAsPanel != null)
       {                
           parentAsPanel.Children.Remove(child);
           return;
       }
       var parentAsContentPresenter = parent as ContentPresenter;
       if (parentAsContentPresenter != null)
       {
           if (parentAsContentPresenter.Content == child)
           {
               parentAsContentPresenter.Content = null;
           }
           return;
       }
       var parentAsContentControl = parent as ContentControl;
       if (parentAsContentControl != null)
       {
           if (parentAsContentControl.Content == child)
           {
               parentAsContentControl.Content = null;
           }
           return;
       }
   }     

   private void ToggleFullScreenModeButton_Click(object sender, RoutedEventArgs e)
   {
       var view = ApplicationView.GetForCurrentView();
       if (view.IsFullScreenMode)
       {
           view.ExitFullScreenMode();                
       }
       else
       {
           if (view.TryEnterFullScreenMode())
           {
               txtresult.Text = "full screen";
           }
           else
           {
               txtresult.Text = "no full screen";
           }
       }
   }
}

我的测试环境是 OS build 15063。如果您仍然有问题,请提供minimal 复制的项目。您可以尝试在我的测试演示中重现该问题。更多详情请引用official sample .

关于c# - UWP 将 child 转移到其他 parent 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46272422/

相关文章:

xaml - 删除弹出控件内 ListViewItem 上的填充

c# - Xamarin Forms UWP - 无法为 .NET Native 工具链编译

c# - 字符串内容相同但长度不同

java - ActiveMQ 5.15.9 安全

c# - 在 c# 中从数据库检索数据到 dataGridView 时出现空行

c# - Excel 互操作 : Quitting the Excel application instance makes my tests fail?

c# - 有没有办法在 WPF 控件库中使用 StaticResource 并能够在设计时查看?

c# - 试图让 Windows Phone 8 ListPicker 工作

c# - 使用私有(private)字段或 DependencyProperty 支持绑定(bind)属性有什么区别?

windows-runtime - 没有方案的 Windows.Web.Http.HttpClient 授权 header 。