2016-11-08 631 views
2

我的目標是創建一個Canvas,您可以通過在整個畫布中移動來將子元素翻譯到您想要的位置(例如,在犀牛的蚱蜢插件中)。我嘗試過使用「translateTransform」,但後來出現的問題是,畫布的高度或寬度不夠大,無法再包括整個窗口。我試圖解決這個問題,只要Canvas被拖動,就將寬度和高度添加到Canvas中,但Canvas的大小似乎沒有改變。如何在WPF中實現「無限大小」的畫布效果?

這裏是我的window.xaml:

<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#代碼:

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; 
    } 

畫布是在開始的網格,但沒有任何工作。它的工作原理是圍繞畫布移動,當然包括所有元素,但如果將它放在窗外,則不能再移動任何東西,因爲畫布不再存在。我如何解決這個問題,讓用戶覺得畫布是無限的?

+0

我嘗試添加一個網格容器周圍原有電網和火在容器上的事件,但僅改造內部網,但不幸的是,這並不解決問題,我不知道爲什麼。 .. – hardking

+0

因此,您有一個視覺區域,它是潛在的無限邏輯區域的一部分,您希望將元素放置在邏輯區域上,並且想要以某種方式拖動它,以避免將邏輯區域的邊緣拖入視覺區域? – grek40

+0

我不確定我是否正確理解了你,但是如果我的答案是肯定的......網格應該可以無限拖曳到右側或左側,但是當拖到窗口的邊界時,然後執行在中間右鍵單擊顯示網格剛剛完全移動到左側或右側,無法在此鼠標位置翻譯 – hardking

回答

0

在這種情況下,你應該圍繞你的GridScrollView每滴`網格」外拖動的元素後編輯WidthHeight性能。事情是這樣的:

private void UIElement_OnPreviewMouseMove(object sender, MouseEventArgs e) 
    { 
     Control c = (Control)sender; 
     if (canmove) //field is used to define whether element dragged or not 
     { 
      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

這種方式像mousebuttondown事件不能被解僱了 – hardking

+0

@hardking,據我所知,你不能沒有這個事件? –

+0

正是我需要這些事件,因爲我想創建一個彈出窗口,例如當有人點擊畫布 – hardking

相關問題