2017-12-20 4 views
-1

현재 C#/WPF에서 제품 구성자를 작성 중입니다. 이 제품은 커스텀 콘센트 스트립과 같습니다. 가변 길이의 알루미늄 프로파일로 만들어졌습니다. 콘센트를 선택하여 알루미늄 프로파일을 따라 배치 할 수 있습니다.C#/WPF 제품 구성자/드래그 가능 항목

이미 데이터 모델이 있습니다. 우리는 "길이"와 같은 속성을 가진 "프로필"클래스와 "위치", "유형"과 같은 속성을 가진 클래스 "아이템"을 가지고 있습니다.

나는 데이터를 시각화하기 위해 funktion을 만들었습니다. 나는 MainCanvas에서 직사각형으로 프로파일을 그리는 곳이 있고 witdth에는 "width"속성을 사용하고 있습니다. 해당 제품에 속한 항목이 목록에 있습니다. 나는 for-loop를 사용하여 아이템을 그리는 중입니다. "items"목록의 각 플러그에 대해 wpf를 삽입합니다.

데이터를 변경할 때 캔버스를 지우고 다시 그려야합니다. 다음 단계는 클래스의 변수를 WPF 속성에 바인딩하는 것입니다 (예 : 플러그의 위치 또는 프로파일의 lenth).

나중에 플러그를 선택/드래그하여 위치를 변경해야합니다 (예 : 5mm 눈금). 그게 내가 붙어있는 파인트 야. "OnLeftMouseButton"과 같은 액션으로 플러그를 선택하고 드래그 할 수 있다는 것을 알고 있습니다. 문제는 다음과 같습니다. 어떤 유형의 컨테이너에 플러그를 넣어야합니까?

저는 WPF 코드를 UserControl 내부에 래핑 할 수 있다고 생각했습니다. 그것이 올바른 접근 방법입니까? 내가 아는 한, Hittest로 UserControl을 선택할 수 있습니다. Hittestresult가 선택된 목록에 놓이게됩니다. 선택 항목을 표시하기 위해 UserControl의 Borderthickness/Brush를 사용할 수 있습니다. 드래그를 위해 ManupilationDelta로 위치를 변경하고 바인딩 된 Position-Variable을 변경할 수 있습니다. 플러그의 개수가 다양하기 때문에 C# -Code에서 UserControls를 생성해야합니다. Hittest는 실제로 보이지 않기 때문에 UserControls를 사용하여 구현하는 것이 쉽지 않다는 것을 알고 있습니다.

저는 C#을 처음 접했고 비슷한 문제 나 프로젝트를 가진 인터넷에서 누군가를 찾는 데 어려움을 겪었습니다. 잘못된 단어를 검색하고 있기 때문일 수 있습니다. 내 가정이 맞습니까? 어떤 WPF 컨트롤을 사용 하시겠습니까?

+0

질문을 단순화해야합니다. 코딩 문제로 곧바로 이동하고 가능한 경우 일부 코드를 공유하십시오. 기본적으로 스냅 핑 그리드에서 드래그 앤 드롭을하고 싶습니다. 맞습니까? 당신은 이미 무엇을 시도 했습니까? – Bob

+0

네, 기본적으로하고 싶습니다. 내 코드는 공유 할 수 있지만 쓰레기는 다. 테스트를 위해 플러그를위한 직사각형이있는 "간단한"프로젝트를 만들었습니다 (일반적으로 여러 모양이 포함되어 있음). 사각형을 캔버스에 넣고 캔버스를 maincanvas에 넣었습니다. 캔버스 테두리를 지원하지 않는 및 사용자 상호 작용을 할, 나는 더 나은 UserControl 안에 사각형을 넣을 생각. 다시 작성하기 전에 플러그 기하학에 적합한 "컨테이너"가 있는지 확인하고 싶습니다. 또한 내 문제는 매우 구체적이며 솔직히 더 잘 설명하는 방법을 모른다 .. – Alex

답변

0

나는 this answer을 사용했고 몇 가지 수정 사항을 추가했습니다.

ItemControl을 사용하여 다른 개체가 포함 된보기를 만들었습니다. 이렇게하면 개체를 목록에 추가하여 이미지를 추가 할 수 있습니다. 컨테이너는 Canvas이지만 위치가 RenderTransform에 의해 제어되기 때문에 아무것도 할 수 있습니다 : 여기

<ItemsControl Name="MainView" ItemsSource="{Binding ListObjects}"> 
    <ItemsControl.ItemsPanel > 
     <ItemsPanelTemplate> 
      <Canvas/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate DataType="{x:Type local:MVDragableObject}"> 
      <local:DragableObject/> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

뒤에 코드입니다. 일부 기본 ModelView :

public class MVObjectManager 
{ 
    public ObservableCollection<MVDragableObject> ListObjects { get; set; } 
    public MVObjectManager() 
    { 
     ListObjects = new ObservableCollection<MVDragableObject>(); 
    } 
} 
public class MVDragableObject 
{ 
} 

그리고 컨테이너를 채우고 바인딩하는 코드. 당신은 내가 컬렉션에 3 개 항목을 추가 한 것을 알 수 있습니다

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     MVObjectManager Manager=new MVObjectManager(); 
     Manager.ListObjects.Add(new MVDragableObject()); 
     Manager.ListObjects.Add(new MVDragableObject()); 
     Manager.ListObjects.Add(new MVDragableObject()); 
     MainView.DataContext = Manager; 
    } 
} 

내가 UserControl 아주 간단한 정의.

<UserControl x:Class="StackFill.DragableObject" 
     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"> 
<Grid> 
    <Rectangle Fill="Red" Height="30" Width="30"/> 
</Grid> 

</UserControl> 

을 그리고 여기에 뒤에 코드입니다 드래그를 관리하고 행동 드롭 : 그것은 당신에게 달려을 사용자 정의 할 수 있습니다

public partial class DragableObject : UserControl 
{ 
    public DragableObject() 
    { 
     InitializeComponent(); 
     this.MouseLeftButtonDown += new MouseButtonEventHandler(DragableObject_MouseLeftButtonDown); 
     this.MouseLeftButtonUp += new MouseButtonEventHandler(DragableObject_MouseLeftButtonUp); 
     this.MouseMove += new MouseEventHandler(DragableObject_MouseMove); 
    } 

    protected bool isDragging; 
    private Point clickPosition; 

    private void DragableObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     isDragging = true; 
     var draggableControl = sender as UserControl; 
     clickPosition = e.GetPosition(this.Parent as UIElement); 
     draggableControl.CaptureMouse(); 
    } 

    private void DragableObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     isDragging = false; 
     var draggable = sender as UserControl; 
     draggable.ReleaseMouseCapture(); 
    } 

    private void DragableObject_MouseMove(object sender, MouseEventArgs e) 
    { 
     var draggableControl = sender as UserControl; 

     if (isDragging && draggableControl != null) 
     { 
      Point currentPosition = e.GetPosition(this.Parent as UIElement); 

      var transform = draggableControl.RenderTransform as TranslateTransform; 
      if (transform == null) 
      { 
       transform = new TranslateTransform(); 
       draggableControl.RenderTransform = transform; 
      } 

      transform.X = snapPosition(currentPosition.X - clickPosition.X, 10); 
      transform.Y = snapPosition(currentPosition.Y - clickPosition.Y, 10); 
     } 
    } 

    private double snapPosition(double position, double gridSize) 
    { 
     return (Math.Truncate(position/gridSize) * gridSize); 
    } 
} 

당신은 gridSize 인수를 변경하여 스냅 정밀도를 제어 할 수 있습니다 .

+0

와우는 답을 알려 줘서 고마워! MainWindow.xaml ()에서 오류가 발생합니다 : MVDragableObject is not clr-namespace. 로컬 : "MVDragableObject"를 "DragableObject"로 편집하면 Visual Studio에 오류가 표시되지 않지만 빌드가 실패합니다. 여기에 몇 가지 이름 문제가 있다고 생각합니다. – Alex

+0

Nervermind가 클래스 MVObjectManager를 잘못 배치했습니다. UserControl의 코드 숨김이 아닙니다. 기본적으로 그 일. 나는 약간의 조정을하고 코드를 게시 할 것이다. 감사! – Alex