两个XAML页面后面有相同的代码

时间:2014-10-18 12:03:12

标签: c# wpf xaml windows-phone-8 windows-runtime

我正在创建一个Windows通用应用程序(WinRT和WP8.1)。 我想要的是让用户在同一页面的两个不同布局之间进行选择。 下面是简单表示。 我想找到最简单,最懒惰的方法(我知道我可以创建两个页面,但必须有更好的方法。) 我已经创建了1个页面(500行C#代码后面处理控件交互),现在需要添加第二个布局。这两个布局具有完全相同的功能,控件具有相同的名称,它们的排列方式不同。

在Android中,我可以这样做:

if(IsLayout1Selected)
    setContentView(R.layout.activity_d2p_layout1);

else
    setContentView(R.layout.activity_d2p_layout2);

提前感谢您的帮助!

布局1:

<Page x:Name="d2pPageLayout1"
x:Class="_MyApp.D2P"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:_MyApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" Unloaded="PageUnloaded" Loaded="PageLoaded"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid x:Name="mainGrid">
        <Button x:Name="button1" VerticalAlignment="Top" Click="buttonClick"/>
        <TextBlock x:Name="textblock1" Text="Hello"/>
        <!-- Of course there are a lot more elements and they have many layout properties that differ -->
    </Grid>
</Page>

布局2:

<Page x:Name="d2pPageLayout2"
x:Class="_MyApp.D2P"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:_MyApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" Unloaded="PageUnloaded" Loaded="PageLoaded"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid x:Name="mainGrid">
        <Button x:Name="button1" VerticalAlignment="Bottom" Click="buttonClick"/>
        <TextBlock x:Name="textblock1" Text="Hello"/>
        <!-- Of course there are a lot more elements and they have many layout properties that differ -->
    </Grid>
</Page>

代码背后(布局1和布局2相同):

namespace _MyApp
{
    public sealed partial class D2P : Page
    {
    public D2P()
        {
            this.InitializeComponent();
        }

    private void PageLoaded(object sender, RoutedEventArgs e)
        {
            // do stuff here
        }

    private void PageUnloaded(object sender, RoutedEventArgs e)
        {
            // do some other stuff here
        }

    private void buttonClick(object sender, RoutedEventArgs e)
        {
            // handle buttonClick here
            // a lot of this code also references the controls directly e.g.
            textblock1.Text = "Button 1 was clicked";
        }
    }
}

修改

感谢Akshay Soam的提示,我使用DataTemplate和ContentControl非常接近我想要的东西,但现在这导致了另一个问题,破坏了我的代码。我的代码直接访问了很多元素。 示例:

textblock1.Text = "Button 1 was clicked";

由于我的整个页面内容现在都包含在DataTemplate中,我无法再访问这些元素。我该怎么做?

目前的实施是:

XAML:

<Page.Resources>
    <DataTemplate x:Key="template1">
        <Button x:Name="button1" VerticalAlignment="Bottom" Click="buttonClick"/>
        <TextBlock x:Name="textblock1" Text="Hello"/>
    </DataTemplate>
</Page.Resources>
<ContentControl x:Name="contentControl" Content="{Binding}"/>

代码背后:

contentControl.ContentTemplate = template1;
this.DataContext = template1;

3 个答案:

答案 0 :(得分:1)

至于您的新问题,您可以浏览VisualTree并将其解压缩。

以下是我对该主题的旧回答之一:VisualTree Helper


但不要这样做。您希望使用MVVM模式并将.Text绑定到ModelView的属性,并将该Button绑定到该ModelView的Command。这样你可以更改属性并通过INotifyPropertyChanged ---更改.Text属性,它将自动使用新的更改更新TextBox。


我写的一篇非常容易阅读的MVVM文章回答了相关的SO问题。它也有Button命令。不幸的是,这不是WinForms所以你必须遵守规则。

Implement a ViewModel Single Command with CommandParamater

答案 1 :(得分:0)

我猜您可以在XAML应用中共享相同的布局(Universal)代码,例如对GUIWin使用相同的WP 。但您无法为WinWP内的网页分享相同的用户界面代码。

Tips and tricks for using XAML controls in your universal Windows apps

答案 2 :(得分:0)

您可以为同一页面构建多个xaml,如下所示: 我为不同屏幕尺寸的相同MainPage构建了8个xaml

public sealed partial class MainPage : Page
{


    public MainPage()
    {

        Rect bounds = ApplicationView.GetForCurrentView().VisibleBounds;
        double scaleFactor = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
        Size size = new Size(bounds.Width * scaleFactor, bounds.Height * scaleFactor);



        string resourceName;

        if (size.Width >= 1920 && size.Height >= 1080) resourceName = "ms-appx:///MainPage.layout-1920x1080.xaml";
        else if (size.Width >= 1680 && size.Height >= 1050) resourceName = "ms-appx:///MainPage.layout-1680x1050.xaml";
        else if (size.Width >= 1600 && size.Height >= 1200) resourceName = "ms-appx:///MainPage.layout-1600x1200.xaml";
        else if (size.Width >= 1360 && size.Height >= 768) resourceName = "ms-appx:///MainPage.layout-1360x768.xaml";
        else if (size.Width >= 1280 && size.Height >= 1024) resourceName = "ms-appx:///MainPage.layout-1280x1024.xaml";
        else if (size.Width >= 1024 && size.Height >= 768) resourceName = "ms-appx:///MainPage.layout-1024x768.xaml";
        else if (size.Width >= 720 && size.Height >= 480) resourceName = "ms-appx:///MainPage.layout-720x480.xaml";
        else resourceName = "ms-appx:///MainPage.layout-640x480.xaml";

        this.InitializeComponent(new Uri(resourceName, UriKind.Absolute));

    }



}

}

这些是您可以将其用于场景的代码的链接
https://developer.microsoft.com/en-us/windows/iot/samples/digitalsign

https://github.com/ms-iot/samples/tree/develop/DigitalSign