2013-08-04 1 views
1

본질적으로 경로를 만드는 상호 연결 조각 이미지를 선택할 수있는 작은 프로그램을 만들고 싶습니다. . 그 아이디어는 경로의 다음 부분을 연결할 수있는 버튼이있는 시작 부분을 갖는 것입니다. 이 버튼을 클릭하면 거기에 배치 할 수있는 옵션을 제공 한 다음 선택한 이미지를 배치하고 단추를 경로의 새 끝으로 옮깁니다.클릭하면 그림으로 단추가 교체되고 WPF에서는 그림 위에 새 단추가 생성됩니다.

내 문제는 내 C# 환경이 정적 UI와 텍스트 필드 또는 전체 새 창 조작에 국한되어 있다는 것입니다. 나는 단추가 움직이고 프로그램의 처음 시작 후에 이미지가 놓이는 UI를 만들기 위해 어디에서 시작해야하는지에 대한 단서가 없다. 어쩌면 그리드 컨트롤과 일부 코드를 조작하여 대답일지도 모른다고 생각했지만 정말 그렇게 할 명령을 모른다. 이전 프로그램에 WPF를 사용하고 있으며이 경우 여전히 실행 가능하다고 가정합니다.

아무도 내 목표를 달성하기 위해 프로그램 창의 섹션을 동적으로 제어하는 ​​방법을 알기에 올바른 방향으로 나를 가리킬 수 있습니까? 세미 - 애매한 질문에 대해 유감스럽게 생각하지만, 이것은 여전히 ​​아주 조잡한 취미 애호가 프로그래머로서 휠체어에서 빠져 나온다.

답변

1

다음은 빠르고 간단하지만 예제에서는 런타임에 컨트롤을 추가하고 배치하는 몇 가지 기본 사항을 보여줍니다.

유의할 것들 : 당신은 X를 배치 할 수 있도록하려면

  • 가 명시 적으로 캔버스에 Y를 컨트롤을 추가합니다.
  • 위치 항목에 UserControls를 사용하고 방금 인스턴스를 추가했습니다.
  • 게임을 제작하는 중이며 크기와 복잡성이 큰 경우 WPF를 사용하지 마십시오. 나는 거기에 있었고, 그걸 다 해냈고, 멀티 플레이어 우주 아케이드/액션 게임을 만들었다. 게임에는 너무 느립니다.

다음은 코드 덤프입니다.

//PathBuilding.xaml

<Window 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:TravianResourceProd" x:Class="TravianResourceProd.PathBuilding" 
     Title="PathBuilding" Height="466.377" Width="621.509"> 
    <Grid x:Name="drawingGrid" Background="#FFC2C2C2" > 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition/> 
      <ColumnDefinition Width="0*"/> 
     </Grid.ColumnDefinitions> 
     <Canvas Background="#FFB3B3B3" Margin="0,0,0,-0.377" x:Name="DrawCanvas" MouseMove="DrawCanvas_MouseMove" MouseUp="Grid_MouseUp"> 
      <local:ActiveLocation x:Name="primarySegment" HorizontalAlignment="Left" VerticalAlignment="Top" Loaded="ActiveLocation_Loaded" Canvas.Left="67" Canvas.Top="98"/> 

     </Canvas> 
    </Grid> 
</Window> 

//PathBuilding.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Shapes; 

namespace TravianResourceProd 
{ 
    /// <summary> 
    /// Interaction logic for PathBuilding.xaml 
    /// </summary> 
    public partial class PathBuilding : Window 
    { 
     public PathBuilding() 
     { 
      InitializeComponent(); 
      _ConnectorLine = new Line(); 
      _ConnectorLine.Stroke = new SolidColorBrush(Colors.DarkBlue); 
      _ConnectorLine.Visibility = System.Windows.Visibility.Hidden; 
      _locationSelector = new LocationOptions(); 
      _locationSelector.Visibility = System.Windows.Visibility.Hidden; 
      DrawCanvas.Children.Add(_ConnectorLine); 
      DrawCanvas.Children.Add(_locationSelector); 

     } 

     private Line _ConnectorLine; 
     private bool _AddMode = false; 


     private LocationOptions _locationSelector; 

     private void ActiveLocation_Loaded(object sender, RoutedEventArgs e) 
     { 
      primarySegment.btnAddSegment.Click += (object sender1, RoutedEventArgs e1) => 
      { 
       //show the type selector 
       _locationSelector.Visibility = System.Windows.Visibility.Visible; 
       var loc = _locationSelector.TransformToAncestor(drawingGrid) 
          .Transform(new Point(0, 0)); 
       Canvas.SetLeft(_locationSelector, Mouse.GetPosition(DrawCanvas).X + 80); 
       Canvas.SetTop(_locationSelector, Mouse.GetPosition(DrawCanvas).Y - 50); 

      }; 
      _locationSelector.btnTypeOne.Click += (object s, RoutedEventArgs e2) => 
      { 
       _AddMode = true; 
       _ConnectorLine.Visibility = System.Windows.Visibility.Visible; 
       _locationSelector.Visibility = System.Windows.Visibility.Hidden; 
      }; 
     } 

     private void Grid_MouseUp(object sender, MouseButtonEventArgs e) 
     { 
      if (!_AddMode) 
       return; 
      _AddMode = false; 
      _ConnectorLine.Visibility = System.Windows.Visibility.Hidden; 

      //Add the one we picked 
      var oldLoc = new OldLocation(); 
      Canvas.SetLeft(oldLoc, Canvas.GetLeft(primarySegment)); 
      Canvas.SetTop(oldLoc, Canvas.GetTop(primarySegment)); 
      DrawCanvas.Children.Add(oldLoc); 

      //Add a line connecting old to new 
      var newestLine = new Line(); 
      newestLine.Visibility = System.Windows.Visibility.Visible; 

      newestLine.Stroke = new SolidColorBrush(Colors.Brown); 

      newestLine.X1 = _ConnectorLine.X1; 
      newestLine.Y1 = _ConnectorLine.Y1; 
      newestLine.X2 = _ConnectorLine.X2 + 40; 
      newestLine.Y2 = _ConnectorLine.Y2 + 50; 
      DrawCanvas.Children.Add(newestLine); 

      //Move the active/primary to the new location 
      Canvas.SetLeft(primarySegment, e.GetPosition(this).X); 
      Canvas.SetTop(primarySegment, e.GetPosition(this).Y); 

     } 

     private void DrawCanvas_MouseMove(object sender, MouseEventArgs e) 
     { 
      try 
      {//reposition the line going from active location to mouse 
       _ConnectorLine.X1 = Canvas.GetLeft(primarySegment) + 70; 
       _ConnectorLine.Y1 = Canvas.GetTop(primarySegment) + 50; 
       _ConnectorLine.X2 = e.GetPosition(this).X - 5; 
       _ConnectorLine.Y2 = e.GetPosition(this).Y - 5; 
      } 
      catch (Exception) 
      { 
      } 
     } 
    } 
} 

//LocationOptions.xaml

<UserControl x:Class="TravianResourceProd.LocationOptions" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" Height="109.359" Width="117.057"> 
    <Grid Margin="0,0,-0.17,0.094"> 
     <Button x:Name="btnTypeOne" Content="Type One" HorizontalAlignment="Left" VerticalAlignment="Top" Width="117" Height="33" Margin="0,0,-0.17,0" /> 
     <Button x:Name="btnTypeTwo" Content="Type Two" HorizontalAlignment="Left" VerticalAlignment="Top" Width="117" Margin="0,38,-0.17,0" Height="33" /> 

    </Grid> 
</UserControl> 

//OldLocation.xaml

<UserControl x:Class="TravianResourceProd.OldLocation" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" Height="80" Width="80"> 
    <Grid> 
     <Ellipse Stroke="#FF686868" StrokeThickness="8"> 
      <Ellipse.Fill> 
       <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
        <GradientStop Color="#FF373737" Offset="1"/> 
        <GradientStop Color="#FF929292"/> 
       </LinearGradientBrush> 
      </Ellipse.Fill> 
     </Ellipse> 

    </Grid> 
</UserControl> 
,363,210

//ActiveLocation.xaml

<UserControl x:Class="TravianResourceProd.ActiveLocation" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" Height="80" Width="80"> 
    <Grid> 
     <Ellipse Stroke="#FF1A9000" StrokeThickness="6"> 
      <Ellipse.Fill> 
       <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
        <GradientStop Color="#FF62745E" Offset="1"/> 
        <GradientStop Color="#FF929292"/> 
       </LinearGradientBrush> 
      </Ellipse.Fill> 
     </Ellipse> 
     <Button x:Name="btnAddSegment" Content="" HorizontalAlignment="Left" VerticalAlignment="Top" Width="20" Height="22" FontSize="30" Margin="60,30,-0.302,0"/> 

    </Grid> 
</UserControl> 
+0

이 굉장하다! 캔버스의 사용은 내 필요에 정확하게 부합합니다. UserControls처럼 여기에있는 모든 것을 이해하는 데 조금 시간이 걸릴 것입니다. 우리를 우연히 만나지 않았다. 하지만 그렇지 않으면 이것이 내가 필요한 것입니다. 감사합니다. –

+0

MsPaint에서 이미지를 생성하기에는 너무 게으므로 UserControls를 사용했습니다. 거기에 Image 컨트롤을 던져서 이미지 소스를 설정할 수 있습니다. Ellipse/Rectangle/Line과 같은 Shape 유형을 사용하여 기본 드로잉을 수행하는 것에 대한 한 가지 좋은 점은 WPF에서 수행하는 벡터 기반 렌더링이므로 품질 손실없이 위아래로 확장됩니다. –

관련 문제