1

DataTemplate を使用して、ポイントのコレクションを線の束としてレンダリングすることは可能ですか (データ バインディングとドラッグ アンド ドロップを使用)。

詳細は次のとおりです。

ビュー モデルに複数のオブジェクトがあります。これらのオブジェクトは、最終的に絶対ピクセル座標で指定されたキャンバス上の位置を持ちます。これらのアイテムをキャンバス上にドラッグ アンド ドロップして、座標を更新できるようにする必要があります。点で表されるオブジェクトもあれば、線分の集合で表されるオブジェクトもあります。私はMVVM(Jounce)を使用しています。私のビューモデルはObservableCollection<Shape>、何らかの方法で座標をバインドする を公開する必要がありますか? それは間違っていると感じます。または、ここで DataTemplates を使用して、線分のコレクションを指定して、各線分の端に点を持つ線を描画する方法はありますか? ViewModel の例を次に示します。

using System.Collections.Generic;
using System.Collections.ObjectModel;
using Jounce.Core.ViewModel;

namespace CanvasBindTest.ViewModels
{
    /// <summary>
    /// Sample view model showing design-time resolution of data
    /// </summary>
    [ExportAsViewModel(typeof(MainViewModel))]
    public class MainViewModel : BaseViewModel
    {
        public MainViewModel()
        {
            var start = new PointView { X = 0, Y = 0 };
            var middle = new PointView { X = 1132 / 2, Y = 747 / 2 };
            var end = new PointView() { X = 1132, Y = 747 };
            var lineView = new LineView(new[] { start, middle, end });
            Lines = new LinesView(new[] { lineView });
        }

        public LinesView Lines { get; private set; }
    }

    public class LinesView : BaseViewModel
    {
        public ObservableCollection<LineView> Lines { get; private set; }

        public LinesView(IEnumerable<LineView> lines)
        {
            Lines = new ObservableCollection<LineView>(lines);
        }
    }

    public class LineView : BaseViewModel
    {
        public ObservableCollection<PointView> Points { get; private set; }

        public LineView(IEnumerable<PointView> points)
        {
            Points = new ObservableCollection<PointView>(points);
        }
    }

    public class PointView : BaseViewModel
    {
        private int x, y;

        public int X
        {
            get { return x; }
            set { x = value; RaisePropertyChanged(() => X); }
        }

        public int Y { 
            get { return y; }
            set { y = value; RaisePropertyChanged(() => Y); }
        }
    }
}

これは、背景イメージを持つ ItemsControl でラップされたキャンバスです。ビュー モデルの座標は、背景画像のスケーリングされていないサイズに相対的です。

<UserControl x:Class="CanvasBindTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:viewModels="clr-namespace:CanvasBindTest.ViewModels" 
    mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400">

    <UserControl.Resources>
        <DataTemplate x:Key="SkylineTemplate" DataType="viewModels:LineView">
            <ItemsControl ItemsSource="{Binding Points}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <!--I have a collection of points here, how can I draw all the lines I need and keep the end-points of each line editable?-->
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </DataTemplate>
    </UserControl.Resources>

    <Grid d:DataContext="{d:DesignInstance viewModels:MainViewModel, IsDesignTimeCreatable=True}">
        <ScrollViewer x:Name="Scroll">
            <ItemsControl ItemsSource="{Binding Lines}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas>
                            <Canvas.Background>
                                <ImageBrush Stretch="Uniform" ImageSource="Properties/dv629047.jpg"/>
                            </Canvas.Background>
                        </Canvas>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </ScrollViewer>
    </Grid>
</UserControl>
4

2 に答える 2