2016-09-07 1 views
2

私はキャンバスから継承するカスタムコントロールを構築しました。 ArrangeOverrideメソッドを使用して、すべての子要素にドラッグドロップ機能を追加します。これには、50ピクセルのグリッドスナップと、要素位置の維持などのその他のカスタム動作が含まれます。カスタムWPFキャンバスコントロール内に点のグリッドを描画できますか?

私が実際にやってみたいのは、ドラッグしている間、スナップポイントがどこにあるかを見ることができるように、背景にドットまたは十字のグリッドを表示するようにこれを拡張することです。

ただし、パネルであるためコントロールのテンプレートを変更できません。キャンバスを含むカスタムコントロールを作成し、IEnumerableアイテムのソースを渡してみましたが、コレクションの変更を取り上げるのが難しくなりました。コレクションにはモデルとフレームワーク要素が含まれていませんでした。

私はどちらのパスを取るべきかわかりません。私が見落としてしまった非常に単純な解決策があるかもしれないかのように感じるので、私は提案に公開しています!

ありがとうございます。

答えて

2

私はUserControlでグリッド線を描画し、その上にコントロールを追加することで、同様のことを一度実行しました。それは、今月中にどのようなシフトが働くかを割り当てるために使用される単純なスケジューラーアプリのためのものでした。私は列ヘッダー(日)と行ヘッダー(人)とスクロール可能なグリッドを内部に持っていなければなりませんでした。私の解決策があなたをどの程度まで助けてくれるのかわかりませんが、ここはそうです。

私はHeaderedScrollViewerhereから使用します。 UCHeaderは、UserControlで、日付付きのテキストボックスが回転しています。魔法はUC_GridLinesで起こります。

  • は、子供を含むされる制御用Background="Transparent"の設定が正しくのZIndexの設定
  • を制御し、そのコントロールは、グリッド上に示されています。ここ

    <Grid> 
        <lib:HeaderedScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Background="AliceBlue"> 
        <lib:HeaderedScrollViewer.TopHeader> 
         <lib:UCHeader Name="ucHeader"/> 
        </lib:HeaderedScrollViewer.TopHeader> 
        <lib:HeaderedScrollViewer.LeftHeader> 
         <Border BorderBrush="Black" BorderThickness="1,2,1,1"> 
          <StackPanel Orientation="Vertical" Name="spRows" /> 
         </Border> 
        </lib:HeaderedScrollViewer.LeftHeader> 
        <Grid Name="gridContentAll"> 
         <Border Canvas.ZIndex="1" Background="Transparent" 
          BorderThickness="1,1,1,2" BorderBrush="Transparent"> 
           <Grid ClipToBounds="True" Name="gridContent" Background="Transparent" /> 
         </Border> 
         <Border Canvas.ZIndex="0" BorderThickness="1,1,1,2" BorderBrush="Black" Background="White"> 
          <lib:UC_GridLines Name="ucGridLines" BorderThickness="0"/> 
         </Border> 
        </Grid> 
    </lib:HeaderedScrollViewer> 
    </Grid> 
    

    重要です。そのの.xamlファイルのルート要素(例えばウィンドウ)に

UC_GridLinesをSnapsToDevicePixels="True"UseLayoutRounding="True"を設定

  • は何も(のみ<Grid></Grid>)を持っていません。グリッド線の描画は、コードビハインドで行われます。

    protected override void OnRender(DrawingContext drawingContext) 
        { 
         // VM contains data of the grid, used to draw gridlines 
         // such as number of days etc. 
         if (this.VM == null) 
         { 
          base.OnRender(drawingContext); 
          return; 
         } 
         double dpiFactor = 1; 
         try 
         { 
          Matrix m = PresentationSource.FromVisual(this) 
            .CompositionTarget.TransformToDevice; 
          dpiFactor = 1/m.M11; 
         } 
         catch { } 
    
         Pen pen = new Pen(Brushes.Black, 1 * dpiFactor); 
         double halfPenWidth = pen.Thickness/2; 
    
         GuidelineSet guidelines = new GuidelineSet(); 
    
         double width = this.VM.Days.Count * this.VM.DayWidth - 16 * (this.VM.DayWidth/24); 
         double height = this.VM.RowHeight * rowCount; 
    
         for (int i = 1; i < this.VM.Days.Count; i++) 
         { 
          guidelines.GuidelinesX.Add(i * this.VM.DayWidth + halfDashPenWidth); 
         } 
    
         for (int i = 1; i < rowCount; i++) 
         { 
          guidelines.GuidelinesY.Add(i * this.VM.RowHeight + halfPenWidth); 
         } 
    
         drawingContext.PushGuidelineSet(guidelines); 
    
         for (int i = 1; i < this.VM.Days.Count; i++) 
         { 
          drawingContext.DrawLine(dashpen, new Point(i * this.VM.DayWidth, 0), new Point(i * this.VM.DayWidth, height)); 
         } 
    
         for (int i = 1; i < rowCount; i++) 
         { 
          drawingContext.DrawLine(pen, new Point(0, i * this.VM.RowHeight), new Point(width, i * this.VM.RowHeight)); 
         } 
    
         drawingContext.Pop(); 
        } 
    
  • +0

    ありがとうArie - 本当に役立ちます。私はちょうどカスタムコントロールのOnRenderメソッドをオーバーライドし、グリッドを追加しました。ユーザーが積極的にドラッグしている間、どのようにグリッドを表示することができますか?そのレンダリングメソッドは最初に呼び出されるだけで、コントロールのサイズを変更すると呼び出されます。理想的には、それを表示して非表示にすることは素晴らしいことです。 –

    +0

    決して気にしないでください。私はそれをかなり微妙にしました。また、base.OnRender(drawContext)を最後に追加する必要がありました。そうでないと、ドラッグ/グリッドのスナップのパフォーマンスが何らかの理由で悪くなりました。コードサンプルについてもう一度おねがいします。 –

    関連する問題