如何在WPF中制作多页UserControl?

发布于 2025-01-06 23:38:16 字数 2606 浏览 1 评论 0原文

我正在尝试创建一个包含三个不同页面的用户控件,每个页面显示不同的内容。我的想法是执行以下操作:创建用户控件主网格,然后创建另一个网格,其宽度设置为用户控件或主网格宽度的三倍,然后在其中创建三列。然后,我将为每个列创建一个网格,包裹每个页面内容。接下来,创建两个按钮来滑动页面,通过平移变换动画来更改它们。

我做得很好,但是滑动并没有像我预期的那样工作:当网格平移时,新页面的内容没有显示,而另一个页面在用户控件的一侧保持可见。

问题!

代码如下:

.cs

    private void TranslateMainGrid(bool right)
    {
        DoubleAnimation gridTranslateAnimation = new DoubleAnimation(); // Calculations not important

        gridTranslateAnimation.From = right ? 0 - (this.SelectedPanel - 1) * 286 : 0 - (this.SelectedPanel + 1) * 286;
        gridTranslateAnimation.To = 0 - this.SelectedPanel * 286;
        gridTranslateAnimation.Duration
          = new Duration(new TimeSpan(0, 0, 0, 0, 500));

        TranslateTransform oTransform
          = (TranslateTransform)PanelGrid.RenderTransform;
        oTransform.BeginAnimation(TranslateTransform.XProperty,
          gridTranslateAnimation);
    }

.xaml

<Grid x:Name="MainGrid" Height="400" Width="286" Background="#7B9D9D9D" RenderTransformOrigin="0.5,0.5">

    <Grid x:Name="PanelGrid" Height="400" Width="858" RenderTransformOrigin="0.5,0.5">
        <Grid.RenderTransform>              
            <TranslateTransform X="0"/>
        </Grid.RenderTransform>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>


        <Grid x:Name="ChimeraGrid" Grid.Column="0">
            <Grid.Background>
                <ImageBrush ImageSource="/GameView;component/Resources/arcaneCreature.png"/>
            </Grid.Background>

        </Grid>
        <Grid x:Name="CreatureGrid" Grid.Column="1">
            <Grid.Background>
                <ImageBrush ImageSource="/GameView;component/Resources/chimeraTest.png"/>
            </Grid.Background>
            <Label Content="lolololol" Height="81" VerticalAlignment="Top" HorizontalAlignment="Right" Width="164"/>
        </Grid>

        <Grid x:Name="EquipmentGrid" Grid.Column="2">
            <Grid.Background>
                <ImageBrush ImageSource="/GameView;component/Resources/tribeCreature.png"/>
            </Grid.Background>
        </Grid>
    </Grid>
</Grid>

代码被简化了,但我想它说明了全部内容。我该如何处理这个网格?还有其他方法可以实现我在这里的意图吗?

谢谢

I'm trying to make a user control which contains three different pages, each displaying different content. My idea was to make the following: create the user control main grid, then create another grid with the width set to three times the width of the user control or the main grid, and then create three columns in it. Then I would create a grid for each of the columns, wrapping each page content. Next, create two buttons to slide the pages, changing them through a translate transform animation.

I did it all right, but the sliding doesn't work as I expected: when the grid is translated, the content of the new page doesn't get displayed, and the other page keeps visible in the side of the user control.

The problem!

The code is as follows:

.cs

    private void TranslateMainGrid(bool right)
    {
        DoubleAnimation gridTranslateAnimation = new DoubleAnimation(); // Calculations not important

        gridTranslateAnimation.From = right ? 0 - (this.SelectedPanel - 1) * 286 : 0 - (this.SelectedPanel + 1) * 286;
        gridTranslateAnimation.To = 0 - this.SelectedPanel * 286;
        gridTranslateAnimation.Duration
          = new Duration(new TimeSpan(0, 0, 0, 0, 500));

        TranslateTransform oTransform
          = (TranslateTransform)PanelGrid.RenderTransform;
        oTransform.BeginAnimation(TranslateTransform.XProperty,
          gridTranslateAnimation);
    }

.xaml

<Grid x:Name="MainGrid" Height="400" Width="286" Background="#7B9D9D9D" RenderTransformOrigin="0.5,0.5">

    <Grid x:Name="PanelGrid" Height="400" Width="858" RenderTransformOrigin="0.5,0.5">
        <Grid.RenderTransform>              
            <TranslateTransform X="0"/>
        </Grid.RenderTransform>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>


        <Grid x:Name="ChimeraGrid" Grid.Column="0">
            <Grid.Background>
                <ImageBrush ImageSource="/GameView;component/Resources/arcaneCreature.png"/>
            </Grid.Background>

        </Grid>
        <Grid x:Name="CreatureGrid" Grid.Column="1">
            <Grid.Background>
                <ImageBrush ImageSource="/GameView;component/Resources/chimeraTest.png"/>
            </Grid.Background>
            <Label Content="lolololol" Height="81" VerticalAlignment="Top" HorizontalAlignment="Right" Width="164"/>
        </Grid>

        <Grid x:Name="EquipmentGrid" Grid.Column="2">
            <Grid.Background>
                <ImageBrush ImageSource="/GameView;component/Resources/tribeCreature.png"/>
            </Grid.Background>
        </Grid>
    </Grid>
</Grid>

The code was simplified, but I guess it ilustrates the whole stuff. How can I deal with this grids? Is there any other way to do what I intended here?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我不咬妳我踢妳 2025-01-13 23:38:16

将顶级网格替换

<Grid x:Name="MainGrid" Width="286" ...>

为 Canvas 并设置 ClipToBounds 属性:

<Canvas Name="MainCanvas" Width="286" ClipToBounds="True">

此外,您还必须设置三列中没有任何内容的网格的 Height 属性。仅设置 ImageBrush 的背景不会影响网格的大小。结果是三个 Grid 具有 Width=286(由 858 除以三列得出),但左右 Grid 具有 Height=0,因为它们没有内容。中间的标签从包含的标签中获取其高度,因此是可见的。

您还可以在每列网格中放置一个图像控件,而不是设置 ImageBrush。这样三个网格的高度就会自动设置。

当然,ClipToBounds 也适用于 Grid,但当 RenderTransform 应用于该内容时,Grid 似乎不会重新渲染其内容的任何以前不可见的部分。

使用 Canvas 时,您还可以考虑对 Canvas.Left 属性进行动画处理,而不是使用 TranslateTransform。

编辑:这是我的测试程序中的 XAML:

<Window x:Class="SlidingGrid.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="500" Width="400">
    <Canvas Width="286" ClipToBounds="True" Margin="10">
        <Grid Width="858" Name="grid" Canvas.Left="0" Height="400">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Grid.RenderTransform>
                <TranslateTransform x:Name="slideTransform"/>
            </Grid.RenderTransform>
            <Grid Grid.Column="0">
                <Grid.Background>
                    <ImageBrush ImageSource="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg" Stretch="UniformToFill"/>
                </Grid.Background>
            </Grid>
            <Grid Grid.Column="1">
                <Grid.Background>
                    <ImageBrush ImageSource="C:\Users\Public\Pictures\Sample Pictures\Penguins.jpg" Stretch="UniformToFill"/>
                </Grid.Background>
            </Grid>
            <Grid Grid.Column="2">
                <Grid.Background>
                    <ImageBrush ImageSource="C:\Users\Public\Pictures\Sample Pictures\Tulips.jpg" Stretch="UniformToFill"/>
                </Grid.Background>
            </Grid>
        </Grid>
    </Canvas>
</Window>

以及代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        Loaded += (o, e) =>
            {
                //grid.BeginAnimation(
                //    Canvas.LeftProperty,
                //    new DoubleAnimation(-572, TimeSpan.FromSeconds(2)));
                slideTransform.BeginAnimation(
                    TranslateTransform.XProperty,
                    new DoubleAnimation(-572, TimeSpan.FromSeconds(2)));
            };
    }
}

Replace your top-level Grid

<Grid x:Name="MainGrid" Width="286" ...>

by a Canvas and set the ClipToBounds property:

<Canvas Name="MainCanvas" Width="286" ClipToBounds="True">

Moreover you have to set the Height property of those Grids in the three columns that don't have any content. Setting only the Background to an ImageBrush will not affect the Grid's size. The result is that the three Grids have Width=286 (resulting from 858 divided by three columns) but the left and right Grid have Height=0, because they have no content. The middle one gets its height from the contained Label and is hence visible.

Instead of setting an ImageBrush you could also put an Image control in each column Grid. Thus the heights of the three Grids would be set automatically.

Of course ClipToBounds also works with a Grid, but it seems that the Grid won't re-render any previously invisible parts of its content when a RenderTransform is applied to that content.

When using a Canvas you may also consider to animate the Canvas.Left property instead of using a TranslateTransform.

EDIT: Here is the XAML from my test program:

<Window x:Class="SlidingGrid.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="500" Width="400">
    <Canvas Width="286" ClipToBounds="True" Margin="10">
        <Grid Width="858" Name="grid" Canvas.Left="0" Height="400">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Grid.RenderTransform>
                <TranslateTransform x:Name="slideTransform"/>
            </Grid.RenderTransform>
            <Grid Grid.Column="0">
                <Grid.Background>
                    <ImageBrush ImageSource="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg" Stretch="UniformToFill"/>
                </Grid.Background>
            </Grid>
            <Grid Grid.Column="1">
                <Grid.Background>
                    <ImageBrush ImageSource="C:\Users\Public\Pictures\Sample Pictures\Penguins.jpg" Stretch="UniformToFill"/>
                </Grid.Background>
            </Grid>
            <Grid Grid.Column="2">
                <Grid.Background>
                    <ImageBrush ImageSource="C:\Users\Public\Pictures\Sample Pictures\Tulips.jpg" Stretch="UniformToFill"/>
                </Grid.Background>
            </Grid>
        </Grid>
    </Canvas>
</Window>

and the code:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        Loaded += (o, e) =>
            {
                //grid.BeginAnimation(
                //    Canvas.LeftProperty,
                //    new DoubleAnimation(-572, TimeSpan.FromSeconds(2)));
                slideTransform.BeginAnimation(
                    TranslateTransform.XProperty,
                    new DoubleAnimation(-572, TimeSpan.FromSeconds(2)));
            };
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文