2017-05-11 8 views
0

キャンバスに要素を描画するアプリケーションをプログラミングしました。これらの要素は長方形です(しかし、私はそれにテキストを入れたいので、私はBorderクラスを使いました)。これらの要素はオブジェクトを表します(私の場合はTask)。WPF:キャンバスへのリソース要素の追加とプロパティのバインド

私はこのような背後にあるコードでこれらの要素を描画:

foreach (var task in TasksList) 
{ 
    var rect = new Border(); 
    rect.Background = (SolidColorBrush)(new 
     BrushConverter().ConvertFrom("#0074D9")); 
    rect.BorderBrush = (SolidColorBrush)(new 
     BrushConverter().ConvertFrom("#001f3f")); 
    rect.BorderThickness = new Thickness(2); 

    rect.Width = 60; 
    rect.Height = 60; 
    var t = new TextBlock 
    { 
     Text = task.Id.ToString(), 
     Foreground = new SolidColorBrush(Colors.White), 
     HorizontalAlignment = HorizontalAlignment.Center, 
     VerticalAlignment = VerticalAlignment.Center 
    }; 
    rect.Child = t; 

    Canvas.SetLeft(rect, coordX); 
    Canvas.SetTop(rect, coordY); 
    Canvas.Children.Add(rect); 
} 

Instedの背後にあるコードでは境界線(RECT)を設計します。私はそれをXAMLリソースとして設計し、このリソースのインスタンスをコードの背後に作成したいと考えています。どのようにこれを達成することができますか? この場合バインディングはどのように使用できますか?たとえば、xamlリソースでは、タスクのプロパティIDをボーダーの中央に配置されたTextBlockのTextプロパティにバインドする必要があることを定義する必要があります。しかし後で、コードの背後に、どのようにxamlで定義されたプロパティのDataContextを指定するのですか?

あなたは私を導くことができます。ありがとう

+1

コードの背後にUI要素を作成しないでください。代わりに、ItemsPanelとしてCanvasを持つItemsControlと適切なItemTemplateを使用します。 MSDNの[データテンプレートの概要](https://msdn.microsoft.com/en-us/library/ms742521.aspx)の記事を読んでください。例については、[この質問](http://stackoverflow.com/q/22324359/1136211)も参照してください。 – Clemens

答えて

1

座標値がどこから来るのかはっきりしていないので、それらをTaskItemクラスの一部にしました。あなたはこの側面を変えることができます。

WPF XAMLでコードを実現するには、アイテム(DataTemplate)の視覚的な表現とアイテムの配置を決定する方法が必要です。このスタイルにはスタイルを使用します。アイテムは、Clemensの提案したとおり、ItemsControlというキャンバスに配置されます。

この例では、TaskItemはプレーンなクラスです。作成後に内容を変更する場合は、INotifyPropertyChangedで実装する方がよいでしょう。

<Window.Resources> 
    <DataTemplate x:Key="dtTaskItem" DataType="{x:Type local:TaskItem}"> 
     <Border 
      Background="#0074D9" 
      BorderBrush="#001F3F" 
      BorderThickness="2" 
      Width="60" 
      Height="60"> 
      <TextBlock 
       Text="{Binding Id}" 
       Foreground="White" 
       HorizontalAlignment="Center" VerticalAlignment="Center"/> 
     </Border> 
    </DataTemplate> 

    <Style x:Key="canvasTaskItemStyle" TargetType="ContentPresenter"> 
     <Setter Property="Canvas.Left" Value="{Binding CoordX}"/> 
     <Setter Property="Canvas.Top" Value="{Binding CoordY}"/> 
    </Style> 
</Window.Resources> 
<Grid x:Name="grid1"> 
    <ItemsControl 
     ItemsSource="{Binding TasksList}" 
     ItemTemplate="{StaticResource dtTaskItem}" 
     ItemContainerStyle="{StaticResource canvasTaskItemStyle}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <Canvas/> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
    </ItemsControl> 
</Grid> 

と一緒にプレイするためにいくつかの例のデータ:

var tasksList = new List<TaskItem>() 
{ 
    new TaskItem { Id = 1, CoordX = 10, CoordY = 20 }, 
    new TaskItem { Id = 2, CoordX = 60, CoordY = 160 }, 
    new TaskItem { Id = 5, CoordX = 140, CoordY = 80 }, 
    new TaskItem { Id = 3, CoordX = 50, CoordY = 50 }, 
    new TaskItem { Id = 8, CoordX = 100, CoordY = 100 }, 
}; 
grid1.DataContext = new { TasksList = tasksList }; 

は追記:リソースが同様に配置することができるDataContextを期待

public class TaskItem 
{ 
    public int Id { get; set; } 
    public double CoordX { get; set; } 
    public double CoordY { get; set; } 
} 

XAMLは、TasksListコレクションを含むように内部はGrid.Resourcesセクションです。 Window.Resourcesは、私がWPF関連のstackoverflowに関する質問への回答をテストするときに使用するデフォルトビルドです。 local:TaskItemは、xaml名前空間が現在のプロジェクト(私の場合はxmlns:local="clr-namespace:WpfTests_2")に対して定義されることを期待しています。

+0

ありがとう@ grek40これはまさに私が欲しかったものです。今、私はこの作業をしています。同じキャンバスに2種類のオブジェクトを置くことができますか? 1つはタスク(境界線)を表し、もう1つはタスク間の依存関係(行)を表します。 モデルでは、すべてのタスクには、タスクのリストであるPredecessorTasksというプロパティがあります。 – chincheta73

+0

出発点を与えるには、 'DataTemplate'と' ItemTemplate = "から' x:Key = "dtTaskItem" {StaticResource dtTaskItem} "をItemsControlから削除します。この例でも動作しますが、今回は 'DataType =" {x:Type local:TaskItem} "に基づいてデータテンプレートが暗黙的に選択されています。次のステップ:他のクラスタイプの暗黙的なデータテンプレートを作成します。また、アイテムタイプがリストアイテムに表示されるときにも使用されます。 – grek40

+0

@ grek40ありがとうございます。これもうまくいきました:)次は、作業していない境界線にツールチップを追加することです。しかし、私はこれを新しい質問で尋ねます。ありがとうございました :) – chincheta73

関連する問題