usercontrol的两个实例

时间:2017-07-30 14:03:18

标签: c# xaml uwp user-controls

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

修改 为了使其更易于理解,我已经建立了一个新的"剥离的"项目。我使用了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;
    }
}

问题:当我点击usercontrol 实例1 的按钮时,此实例的splitview窗格会打开,但是当我点击实例2 的按钮后, 实例1 的splitview窗格关闭。为什么会这样?

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

  • 什么是封装(事件,属性)?
  • 用户控件如何与调用页面通信?
  • 他们如何相互沟通?
  • usercontrol.content如何运作?

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

更新 下图显示了单击按钮之前的实时树: Before

,这显示了拆分窗格具有openend时的实时树: After

也许这个&#34; popup root&#34;这是解决方案的暗示吗?

1 个答案:

答案 0 :(得分:0)

我无意中找到了解决方案:我添加了

  

DISPLAYMODE = “内联”

到我的Splitview。我不知道为什么会这样,但我不会抱怨。我将非常感激地接受; - )

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