2011-12-05 5 views
-1

이것은 정말 기본적인 요구 사항이지만 막혀 있습니다! WPF/.Net의 경우 - ListView의 Canvas 열을 동적으로 그립니다. 하나 개의 실패한 시도 : 내 코드 내부ListView 안에 포함 된 캔버스 위젯을 그리는 법

<ListView name="myGridView"> 
    <GridViewColumn Header="ColumnA" DisplayMemberBinding="{Binding Path=ColumnA}" /> 
    <GridViewColumn DisplayMemberBinding="{Binding Path=ColumnB}"> 
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUSPECT! 
     <Canvas Name="canvasColumn" Width="100" Height="20" /> 
    </GridViewColumn> 
</GridView> 

, 나는 비 캔버스의 ListView 열에 바인딩 필드 클래스 "을 MyData"가. ListView에 약간의 "무엇이든"의 작성 항목을 통해 내가 루프 :

foreach (Whatever whatever in whatevers) 
{ 
    MyData myData = new MyData(); 
    myData.ColumnA = whatever.A; 

    myData.ColumnB = new Canvas(); 
    Line line = new Line(); 
    line.Stroke = System.Windows.Media.Brushes.Black; 
    line.X1 = line.Y1 = 1; 
    line.X2 = line.Y2 = 100; 
    line.StrokeThickness = 1; 
    myData.ColumnB.Children.Add(line); 

    myListView.Items.Add(myData); 
} 

이 작동하지 않습니다 : 화면의 캔버스 열의 모든 행은 텍스트 "System.Windows.Controls.Canvas"를 표시합니다. 대단히 놀랍지도 않습니다. 텍스트 열과 같은 방식으로 열을 바인딩했으며 typename의 일부 toString 변환이 시작되는 것 같습니다. 그러나 다른 것들을 시도했지만 Canvas를 표시 할 수 없습니다.

나는 또한 열을 제거하는 시도

리스트 뷰를 통해 캔버스 위젯 형태의, 즉 뭔가를 참조 할 수있는 방법 모색 "SUSPECT"위에 표시하고, MYDATA의 COLUMNB 필드 바인딩 :

myListView.reference-to-new-row-and-canvas-column = theNewCanvasIDrewOn; 

일부를 내 검색의 스타일이 엉망이되어 버렸습니다. ItemPanel 설정 등 : 제발, 적어도 필요한 경우 최소한 유지할 수 있기를 바랍니다.

모든 안내가 크게 감사드립니다.

건배, 토니

내 목적을 위해

은, 최소한의 솔루션은 App.xaml의에 Application.Resources 태그에 DataTemplate을 추가 할 것으로 보인다 UPDATE :

<DataTemplate x:Key="myTemplate"> 
    <Canvas Width="60" Height="20" Background="Red" ClipToBounds="True" > 
     <ContentPresenter Content="{Binding myCanvasField}" /> 
    </Canvas> 
</DataTemplate> 

와 GridViewColumn을 정의 예 :

<GridViewColumn CellTemplate="{StaticResource myTemplate}" Header="title" /> 

올바른 방향으로 나를 가리켜 주신 딘에게 감사 드리며 캔버스 관련 세부 사항은 Binding to Canvas으로 보내주십시오. 그런 다음 ListView에 추가하는 객체의 Canvas 속성 멤버를 "그려"갑니다.

+0

어떤 그림이 있습니까? –

+0

@Dmitry : 목록보기에는 "작업"이 표시되고 시작 날짜, 약속 된 배달 날짜, 예상 배달 날짜 등 막대 그래프가 표시됩니다. 기본적으로 작업 진행 상황을 한 눈에 확인합니다. . 나중에 나는 더 좋아질 수 있고 휴일/휴가 기간 또는 무언가를 나타 내기를 원할 것입니다 .... –

+0

캔버스에 "그림 그리기"에 대해 말하면, 실제로 WPF를 "얻지"않습니다. WPF는 WinForms의 페인트 이벤트와 매우 다른 유지 모드 그래픽을 사용합니다. WPF의 Canvas는 그리기 화면이 아닌 레이아웃 패널입니다. Canvas를 "그리지"마십시오. 컨트롤/요소를 추가합니다. 곡면을 "그리기"하려면 DrawingGroup 또는 WriteableBitmap을 살펴보십시오. –

답변

0

가 여기에 내 걸릴이야을 사용해야합니다. 아이디어는 미니 DSL을 사용하여 캔버스와 비즈니스 객체간에 정보를 교환하는 것입니다.

XAML :

<Window x:Class="DrawInCanvas.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:DrawInCanvas" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <DataGrid x:Name="g"> 
      <DataGrid.Columns> 
       <DataGridTextColumn Header="Id" Binding="{Binding Item1}" /> 
       <DataGridTemplateColumn Header="Bar"> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <Canvas HorizontalAlignment="Left" 
            Height="20" 
           local:CanvasDrawing.Drawing="{Binding Item2}" /> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
       </DataGridTemplateColumn> 
      </DataGrid.Columns> 
     </DataGrid> 
    </Grid> 
</Window> 

코드 :

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
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.Navigation; 
using System.Windows.Shapes; 

namespace DrawInCanvas 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      this.Loaded += new RoutedEventHandler(MainWindow_Loaded); 
     } 

     void MainWindow_Loaded(object sender, RoutedEventArgs e) 
     { 
      // just a sample 
      Dictionary<int, string> barDefinitions = new Dictionary<int, string>(3) 
      { 
       { 1, "100$red" }, 
       { 2, "220$yellow" }, 
       { 3, "40$blue" } 
      }; 

      this.g.ItemsSource = 
       Enumerable.Range(1, 3).Select(t => 
        new Tuple<int, string>(t, barDefinitions[t])); 
     } 
    } 

    public class CanvasDrawing : DependencyObject 
    { 
     public static readonly DependencyProperty DrawingProperty = 
      DependencyProperty.RegisterAttached("Drawing", 
       typeof(string), 
       typeof(CanvasDrawing), 
       new PropertyMetadata(new PropertyChangedCallback((o, e) => 
       { 
        CanvasDrawing.Draw((Canvas)o, (string)e.NewValue); 
       }))); 

     public static void SetDrawing(Canvas canvas, string drawing) 
     { 
      canvas.SetValue(CanvasDrawing.DrawingProperty, drawing); 
     } 

     public static string GetDrawing(Canvas canvas) 
     { 
      return (string)canvas.GetValue(CanvasDrawing.DrawingProperty); 
     } 

     private static void Draw(Canvas canvas, string drawing) 
     { 
      string[] parts = drawing.Split("$".ToCharArray()); 

      canvas.Width = double.Parse(parts[0]); 
      canvas.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString(parts[1])); 
     } 
    } 
} 
+0

안녕하세요 드미트리, 제안과 코드에 감사드립니다. ListView를 포기하고 DataGrid를 채택한 것처럼 이것을 사용하는 방법을 너무 확신하지 못했습니다. 선을 캔버스에 추가하는 방법이나 적절한 "문자열 그리기"값을 생성하는 방법을 알려주지 않습니다. 내가 .NET을 더 많이 아는 경우에 /로 돌아 가기위한 것. 고마워, 토니 –

+0

안녕하세요, 토니, 당신이 찾고있는 일을하는 가장 쉬운 와트는 딘의 대답입니다. –

1

당신은 사용자 정의 컨트롤로 TaskVisualizer을 impliment하고 당신의 목록 템플릿에 그것을 호스팅 할 수 있습니다. 이렇게하면 작업 시각화 코드가 전역 UI 코드와 분리됩니다. 이렇게하면 다른 시각에서 작업 위로 마우스를 가져 가면 같은 그래픽을 툴팁에 쉽게 표시 할 수있는 등 작업 시각화를 쉽게 재사용 할 수 있다는 장점이 있습니다.

+0

안녕하세요. Ricibob, 제안에 감사드립니다. 개념적으로 깨끗하게 들립니다. 그러나 현재 어떻게해야하는지에 대한 통찰력이 없기 때문에보다 최소한의 결합 된 접근 방식을 추구했습니다. 나는 언젠가 이것을 학습 운동으로 시도 할 것입니다. 감사합니다. Tony –

+1

@TonyDelroy : 예, WPF와 마찬가지로 모든 사용자 지정 컨트롤을 정렬하는 데 상당한 가동 시간이 있습니다. 그러나 투자 할 시간이 있다면 보람이 있습니다! 나는 Sams - WPF Control Development Unleashed가이 루트에 관심이있는 경우에 대비하여 좋은 출발점을 찾았다. – Ricibob

관련 문제