首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在WPF中实现“无限大”的画布效果?

如何在WPF中实现“无限大”的画布效果?
EN

Stack Overflow用户
提问于 2016-11-08 17:07:18
回答 1查看 1.2K关注 0票数 2

我的目标是创建一个画布,您只需在整个画布上来回移动,就可以将子元素转换到您想要的位置(例如,在rhino中的蝗虫插件中)。我尝试使用"translateTransform“,但随后出现的问题是画布的高度或宽度不够大,无法再次包含整个窗口。我试图通过在画布上添加宽度和高度来解决这个问题,但画布的大小似乎没有变化。

这是我的window.xaml:

代码语言:javascript
复制
<Window x:Name="Window" x:Class="Oolong.Windows.Project.ProjectPlan"
        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:local="clr-namespace:Oolong.Windows.Project"
        mc:Ignorable="d"
        Title="Projektplan" Height="{DynamicResource {x:Static SystemParameters.PrimaryScreenHeightKey}}" Width="{DynamicResource {x:Static SystemParameters.PrimaryScreenWidthKey}}" WindowStartupLocation="CenterOwner" ShowInTaskbar="False" Icon="/Oolong;component/Resources/Images/icon2.png">
    <Window.Background>
        <ImageBrush ImageSource="/Oolong;component/Resources/Images/ui/canvas_bg.png" TileMode="FlipY"      Stretch="Uniform" AlignmentY="Top"  Viewport="0,0,150,50" ViewportUnits="Absolute" />
    </Window.Background>
    <Canvas x:Name="Grid" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" MouseLeftButtonDown="Grid_OnMouseLeftButtonDown" MouseDown="Grid_MouseDown" MouseMove="Grid_MouseMove" MouseUp="Grid_MouseUp" MouseWheel="Grid_OnMouseWheel" Width="{DynamicResource {x:Static SystemParameters.MaximizedPrimaryScreenWidthKey}}" Height="{DynamicResource {x:Static SystemParameters.MaximizedPrimaryScreenHeightKey}}">
        <Rectangle x:Name="NewTaskRectangle" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="87" Margin="0,0,0,0" Stroke="Black" VerticalAlignment="Top" Width="208" Visibility="Hidden"/>
            <Label x:Name="NewTaskLabel" Content="Gib den Namen der Aufgabe ein..." HorizontalAlignment="Left" Margin="10,17,0,0" VerticalAlignment="Top" Visibility="Hidden"/>
            <TextBox  x:Name="NewTaskTextBox" HorizontalAlignment="Left" Height="23" Margin="10,48,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="189" Visibility="Hidden" KeyUp="NewTaskTextBox_OnKeyUp"/>
            <Border x:Name="NewTaskTemplate" BorderBrush="Black" BorderThickness="2.5" HorizontalAlignment="Left" Height="30" Margin="0" VerticalAlignment="Top" Background="#FFE2C027" Padding="5" Focusable="True" CornerRadius="6" Width="15" Visibility="Hidden" MinWidth="150" MinHeight="30" MouseRightButtonUp="NewTaskTemplate_OnMouseRightButtonUp">
                <Border.ContextMenu>
                    <ContextMenu x:Name="NewTaskContextMenu">
                        <MenuItem x:Name="AddIssueMenuItem" Header="Arbeitsschritt hinzufügen" Click="AddIssueMenuItem_OnClick"/>
                        <MenuItem x:Name="DeleteMenuItem" Header="Löschen" Click="DeleteMenuItem_OnClick"/>
                    </ContextMenu>
                </Border.ContextMenu>
            </Border>
        <Canvas.RenderTransform>
            <TransformGroup>
                <ScaleTransform x:Name="ScaleTransform"/>
                <TranslateTransform x:Name="Tt" />
            </TransformGroup>
        </Canvas.RenderTransform>
    </Canvas>
</Window>

下面是相关的C#代码:

代码语言:javascript
复制
 private void NewTaskTemplate_OnMouseRightButtonUp(object sender, MouseButtonEventArgs e)
    {
        Point position = e.GetPosition(Grid);
        bool hasClickedOnTask = false;
        if (App.ProjectPlan.Tasks != null)
        {
            var tasks = App.ProjectPlan.Tasks.DistinctBy(task => task.Position);
            var selectedTasks =
                tasks.Where(
                (task =>
                    Math.Abs(task.Position.X - position.X + 10) < task.Title.Length*13 &&
                    Math.Abs(task.Position.Y - position.Y) < 20));
            IEnumerable<Task> enumerable = selectedTasks as Task[] ?? selectedTasks.ToArray();
            if (enumerable.Any())
            {
                _selectedTask = enumerable.Last();
                hasClickedOnTask = true;
            }
        }
        if (!hasClickedOnTask) return;
        NewTaskContextMenu.IsOpen = true;
        e.Handled = true;
        SetGridSize();
    }

    Point _mStart;
    Vector _mStartOffset;

    private void SetGridSize()
    {
        Grid.Width += 250;
        Grid.Height += 250;
        Grid.UpdateLayout();
    }

    private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
    {
        Grid.Cursor = Cursors.ScrollAll;
        _mStart = e.GetPosition(Window);
        _mStartOffset = new Vector(Tt.X, Tt.Y);
        Grid.CaptureMouse();
    }

    private void Grid_MouseMove(object sender, MouseEventArgs e)
    {
        if (Grid.IsMouseCaptured)
        {
            Vector offset = Point.Subtract(e.GetPosition(Window), _mStart);

            Tt.X = _mStartOffset.X + offset.X;
            Tt.Y = _mStartOffset.Y + offset.Y;
            SetGridSize();
        }
    }

    private void Grid_MouseUp(object sender, MouseButtonEventArgs e)
    {
        Grid.ReleaseMouseCapture();
        Grid.Cursor = Cursors.Arrow;
    }

    private void Grid_OnMouseWheel(object sender, MouseWheelEventArgs e)
    {
        Point position = e.GetPosition(Window);
        ScaleTransform.CenterX = position.X;
        ScaleTransform.CenterY = position.Y;
        _gridZoom = _gridZoom + e.Delta / 2400.00;
        ScaleTransform.ScaleX = _gridZoom;
        ScaleTransform.ScaleY = _gridZoom;
        if (e.Delta > 0)
        {
            SetGridSize();
        }
        e.Handled = true;
    }

画布一开始是一个网格,但也不起作用。它可以在画布上移动,当然包括所有元素,但如果你把它放在窗外,你就不能再移动任何东西了,因为画布已经不在那里了。我如何解决这个问题,让用户觉得画布是无限的?

EN

回答 1

Stack Overflow用户

发布于 2016-11-08 20:30:49

在这种情况下,你应该用ScrollView包围你的Grid,并在每次将拖拽的元素放到‘`Grid’之外之后编辑WidthHeight属性。如下所示:

代码语言:javascript
复制
private void UIElement_OnPreviewMouseMove(object sender, MouseEventArgs e)
    {
        if (canmove) //field is used to define whether element dragged or not
        {
            var c = (Control) sender;
            c.SetValue(Canvas.LeftProperty, e.GetPosition(Canvas).X - p.X);
            c.SetValue(Canvas.TopProperty, e.GetPosition(Canvas).Y - p.Y);

            var leftprop = Convert.ToDouble(c.GetValue(Canvas.LeftProperty));
            if (leftprop > Canvas.Width)
                Canvas.Width = leftprop + c.Width+10;
           
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40482848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档