【问题标题】:Two instances of a usercontrol用户控件的两个实例
【发布时间】:2017-07-30 14:03:17
【问题描述】:

作为一个新手,我正在尝试为汽车开发一个应用程序。工作区页面包含一个带有两列的网格。这些列(单个或两个)的可见性由单选按钮控制。每列包含一个 WorkspaceUsercontrol 实例。
此用户控件的拆分视图窗格将包含章节、场景等 - 内容将填充不同类型的列表视图项(文本、图像、html 等)。应该可以将列表视图项从一个实例移动到另一个实例拖动,因此一个实例的更改应该由另一个实例反映。这是到目前为止的代码:

编辑 为了使其更易于理解,我构建了一个新的“剥离”项目。我使用了 Windows Template Studio(空白,基本 MVVM)。

MainPage.xaml

    <Page
    x:Class="Test.Views.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:usercontrols="using:Test.Usercontrols"
    xmlns:toolkit="using:Microsoft.Toolkit.Uwp.UI.Controls"
    mc:Ignorable="d">
    <Grid
        x:Name="ContentArea"
        Margin="{StaticResource MediumLeftRightMargin}">

        <Grid.RowDefinitions>
            <RowDefinition x:Name="TitleRow" Height="48"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <TextBlock
            x:Name="TitlePage"
            x:Uid="Main_Title"
            Style="{StaticResource PageTitleStyle}" />

        <Grid 
            Grid.Row="1" 
            Background="{ThemeResource SystemControlPageBackgroundChromeLowBrush}">
            <!--The SystemControlPageBackgroundChromeLowBrush background represents where you should place your content. 
                Place your content here.-->
            <Grid
                Grid.Row="0"
                x:Name="WorkspaceGrid">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition
                        x:Name="Workspace1Column"
                        Width="1*"></ColumnDefinition>
                    <ColumnDefinition
                        x:Name="WorkspaceSplitterColumn"
                        Width="auto"></ColumnDefinition>
                    <ColumnDefinition
                        x:Name="Workspace2Column"
                        Width="1*"></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <!--workspace 1-->
                <usercontrols:MainpageUsercontrol
                    x:Name="WorkspaceUC1"
                    Grid.Column="0"></usercontrols:MainpageUsercontrol>
                <!--Column Grid Splitter-->
                <toolkit:GridSplitter
                    x:Name="MainpageGridSplitter"
                    Grid.Column="1"
                    Width="11"
                    ResizeBehavior="BasedOnAlignment"
                    ResizeDirection="Auto"
                    Background="Gray"
                    Foreground="White"
                    FontSize="13">
                    <toolkit:GridSplitter.Element>
                        <Grid>
                            <TextBlock
                                HorizontalAlignment="Center"
                                IsHitTestVisible="False"
                                VerticalAlignment="Center"
                                Text="&#xE784;"
                                Foreground="Black"
                                FontFamily="Segoe MDL2 Assets"></TextBlock>
                        </Grid>
                    </toolkit:GridSplitter.Element>
                </toolkit:GridSplitter>
                <!--workspace 2-->
                <usercontrols:MainpageUsercontrol
                    x:Name="WorkspaceUC2"
                    Grid.Column="2"></usercontrols:MainpageUsercontrol>
            </Grid>
        </Grid>
    </Grid>
</Page>

MainPage.xaml.cs

using Test.ViewModels;

using Windows.UI.Xaml.Controls;

namespace Test.Views
{
    public sealed partial class MainPage : Page
    {
        public MainViewModel ViewModel { get; } = new MainViewModel();
        public MainPage()
        {
            InitializeComponent();
        }
    }
}

MainPageViewModel.cs

using System;

using Test.Helpers;

namespace Test.ViewModels
{
    public class MainViewModel : Observable
    {
        public MainViewModel()
        {
        }
    }
}

MainpageUsercontrol.xaml

<UserControl
    x:Class="Test.Usercontrols.MainpageUsercontrol"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Test.Usercontrols"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:converter="using:Test.Converters"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">
    <UserControl.Resources>
        <converter:NullableBoolToBoolConverter
            x:Key="NullableBoolToBoolConverter" />
        <Style
            x:Key="HamburgerButtonStyle"
            TargetType="ToggleButton">
            <Setter
                Property="Content"
                Value="&#xE700;" />
            <Setter
                Property="FontFamily"
                Value="Segoe MDL2 Assets" />
            <Setter
                Property="FontSize"
                Value="20" />
            <Setter
                Property="MinHeight"
                Value="48" />
            <Setter
                Property="MinWidth"
                Value="48" />
        </Style>
    </UserControl.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition
                Height="auto"></RowDefinition>
            <RowDefinition
                Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <RelativePanel
            Grid.Row="0"
            Background="WhiteSmoke">
            <ToggleButton
                x:Name="HamburgerButton"
                Style="{StaticResource HamburgerButtonStyle}"
                IsThreeState="False"
                RelativePanel.AlignBottomWithPanel="True"
                RelativePanel.AlignTopWithPanel="True"
                RelativePanel.AlignLeftWithPanel="True"
                IsChecked="{x:Bind WorkspaceSplitview.IsPaneOpen, Mode=TwoWay, Converter={StaticResource NullableBoolToBoolConverter}}"></ToggleButton>
        </RelativePanel>
        <SplitView
            Grid.Row="1"
            x:Name="WorkspaceSplitview"
            IsPaneOpen="False">
            <SplitView.Pane>
                <Grid Background="LightGray">
                    <Grid.RowDefinitions>
                        <RowDefinition
                            Height="1*"></RowDefinition>
                    </Grid.RowDefinitions>
                    <TextBlock
                        Grid.Row="0"
                        Text="ToDo: Listview Navigation"></TextBlock>
                </Grid>
            </SplitView.Pane>
            <SplitView.Content>
                <TextBox
                    Background="BlanchedAlmond"
                    Height="60"
                    Width="200"
                    Text="ToDo: Content"></TextBox>
            </SplitView.Content>
        </SplitView>
    </Grid>
</UserControl>

MainpageUsercontrol.xaml.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236

namespace Test.Usercontrols
{
    public sealed partial class MainpageUsercontrol : UserControl
    {
        public MainpageUsercontrol()
        {
            this.InitializeComponent();
        }
    }
}

NullableBoolToBoolConverter

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Data;

namespace Test.Converters
{
    public class NullableBoolToBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            bool? val = (bool?)value;
            return val.HasValue ? val.Value : false;
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language) => value;
    }
}

问题:当我点击用户控件instance 1的按钮时,该实例的splitview窗格打开,但是当我随后点击instance 2的按钮时, instance 1 的 splitview 窗格关闭。为什么会这样?

我在 UWP 中搜索了很多关于用户控件的信息,但没有找到任何可以深入了解它们的工作原理的内容:

  • 什么是封装(事件、属性)?
  • 用户控件如何与调用页面通信?
  • 它们如何相互通信?
  • usercontrol.content 是如何工作的?

希望我不是唯一一个对用户控件有点困惑的人。

更新 下图显示了单击按钮之前的活动树:

当拆分窗格有 openend 时,这会显示活动树:

也许这个“弹出根”是解决方案的提示?

【问题讨论】:

    标签: c# xaml uwp user-controls


    【解决方案1】:

    一不小心找到了解决办法:我加了

    DisplayMode="内联"

    到我的拆分视图。我不知道为什么会这样,但我不会抱怨。我会感激地接受;-)

    无论如何:有人能够解释这种行为吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多