2017-12-20 1 views
-1

現在、C#/ WPFで製品コンフィグレータをビルドしています。この製品は、カスタムアウトレットストリップのようなものです。これは、可変長のアルミニウムプロファイルで作られています。アウトレットを選択してアルミプロファイルに沿って配置することができます。c#/ WPFプロダクトコンフィギュレータ/ドラッグ可能なアイテム

すでにデータモデルがあります。 "長さ"のようなプロパティと "位置"、 "タイプ"のようなプロパティを持つクラス "項目"のクラス "プロファイル"を持っています。

私はデータを視覚化するためのファンクションを作成しました。私はMainCanvasを持っています。ここで私はプロファイルを長方形として描画しています。そして、私はプロパティ "width"を使っています。その製品に属する項目はリストにあります。私はfor-loopを使ってアイテムを描画して、リスト "items"の各プラグのwpfを挿入します。

データを変更するときに、キャンバスを消去して再描画する必要があります。次のステップでは、クラスの変数をWPFのプロパティ、たとえばプラグの位置またはプロファイルの1/10にバインドすることになります。

その後、プラグを選択/ドラッグして位置を変更する必要があります(たとえば、5mmのグリッド)。それは私が立ち往生しているパイントです。私は "OnLeftMouseButton"のようなアクションでプラグを選択してドラッグできることを知っています。問題は今です:どのタイプのコンテナにプラグを入れる必要がありますか?

私はUserControlの中にプラグのWPFコードをラップすることができると思った。それが正しいアプローチですか?私が知る限り、私はHittestでUserControlを選択可能にすることができます。 Hittestresultが選択されたリストに入れられます。選択を表示するために、UserControlのBorderthickness/Brushを使用することができます。ドラッグするために、私はManupilationDeltaでPositionを変更することができます(そしてバインドされたPosition-Variableを変更することができます)。プラグの数は可変なので、C#コードからUserControlsを生成する必要があります。 Hittestは実際には「可視」ではないので、UserControlsでの作業を実装するのは簡単ではないことがわかります。

私はC#の初心者です。私は間違った言葉を探しているので、似たような問題やプロジェクトでインターネット上で誰かを見つけるのが苦労しています。私の前提は正しいですか? WPFがコントロールするものは何ですか?

+0

質問を単純化する必要があります。コーディングの問題に直ちに進み、可能であればいくつかのコードを共有してください。あなたは基本的にスナップグリッドでドラッグ&ドロップをしたいのですが、そうですか?何を試しましたか? – Bob

+0

はい、基本的に私はそれをしたいと思います。私は自分のコードを共有することができましたが、それはごみの処理です。テストのために、プラグ(通常は複数の図形が含まれています)用の矩形の「シンプルな」プロジェクトを作成しました。私は矩形をキャンバスに、キャンバスをメインキャンバスに入れました。 Canvasは枠線をサポートしておらず、ユーザーとのやりとりをしているので、私は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 
{ 
} 

そして、コンテナを塗りつぶしてバインドするコード。

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を定義して:あなたは、私がコレクションに3つの項目を追加したことに気づくことができます。それは、それをカスタマイズするのはあなた次第です:

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

あなたはグリッド寸法引数を変更することにより、スナップ精度を制御することができます。

+0

ワウは答えに感謝しています! MainWindow.xaml()でエラーが発生します:MVDragableObject is not clr-namespace。 Visual Studioではlocal: "MVDragableObject"を "DragableObject"に編集すると、エラーは表示されませんが、ビルドに失敗します。ここにいくつかの名前の問題があると思います... – Alex

+0

Nervermind、クラスMVObjectManagerが間違った場所にありますUserControlのコードビハインドではありません。基本的には働いている。私はいくつかの調整を行い、コードを投稿します。ありがとう! – Alex

関連する問題