将网格垂直线与WPF中的线对象对齐 [英] Aligning grid vertical line with a point of line object in WPF

查看:63
本文介绍了将网格垂直线与WPF中的线对象对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在画布背景上画一个网格。在这个画布上,我标记了在画布背景上绘制的网格的垂直线。然后在同一个画布中我有ItemsSource,其Panel是另一个Canvas,在那个画布上我使用Points绘制Line对象。最初运行程序时,网格的垂直线与Line对象的点对齐。网格的垂直位置绘制在第30个位置。线上的每个点都与网格的垂直线完全对齐。当触发鼠标滚轮事件时,我想放大线对象。我正在使用ScaleTransform来达到这个目的。



在事件处理程序中,我正在更改画布宽度。假设我使用Scale变换,ScaleX等于4.这意味着新的画布宽度将等于初始宽度* 4。位于画布x轴上1处的点现在将位于画布X轴上的位置4处。所以,我的第7点将位于第28位。我们知道网格的垂直线是在位置30处绘制的。而我的第8点将位于第32位。现在我无能为力。我无法在运行时选择垂直线的位置。如果最初选择30,它必须保持30.当我增加画布的宽度时放大新的网格被绘制。最大放大条件是1个网格矩形中只存在1个点。这意味着垂直线将在位置30处绘制,因此在第30个位置应出现第一个点。



我尝试过:



名称空间CanvasWidthChecker 
{
///< summary>
/// MainWindow.xaml的交互逻辑
///< / summary>
public partial class MainWindow:Window,INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
double scaleFactor = 1;
double deltaDistance = 1;
ulong totalSamples;
const double maximumDeltaDistance = 30;
double maximumScale = maximumDeltaDistance;
列表< Line> verticalLines = new List< Line>();

private double initialWidth;

public double InitialWidth
{
get {return initialWidth; }
set {initialWidth = value; }
}


private double myWidth = 60;

public double MyWidth
{
get {return myWidth; }
设置
{
myWidth = value;
OnPropertyChanged(MyWidth);
}
}
private void Line_Loaded(object sender,RoutedEventArgs e)
{
Line line = sender as Line;

if(line.Y1!= line.Y2)
{
verticalLines.Add(line);
}
}
private ObservableCollection< Graph>线;

public ObservableCollection< Graph>行
{
获得{返回行; }
set {lines = value; }
}
private ObservableCollection< MyLabel>我的列表;
public ObservableCollection< MyLabel> MyList
{
get {return myList; }
设置
{
myList = value;
OnPropertyChanged(MyList);
}
}

private ulong samplecount;

public ulong Samplecount
{
get {return samplecount; }
set {samplecount = value; }
}

public MainWindow()
{
InitializeComponent();
this.Samplecount = 60;
this.InitialWidth = Samplecount;
MyList = new ObservableCollection< MyLabel>();
MyList.Add(new MyLabel(){ContentData =0});
MyList.Add(new MyLabel(){ContentData =30});
Lines = new ObservableCollection< Graph>();
Lines.Add(new Graph(){From = new Point(0,22),To = new Point(18,22)});
Lines.Add(new Graph(){From = new Point(18-0.5,22),To = new Point(18-0.5,7)});
Lines.Add(new Graph(){From = new Point(18,7),To = new Point(24,7)});
Lines.Add(new Graph(){From = new Point(24-0.5,7),To = new Point(24-0.5,22)});
Lines.Add(new Graph(){From = new Point(24,22),To = new Point(60,22)}); // Samplecount为60

DataContext = this;


}

private void OnPreviewMouseWheel(对象发送者,MouseWheelEventArgs e)
{
Canvas canvas =(Canvas)sender;
e.Handled = true;
double deltaValue =(e.Delta> 0)? 1:-1;
deltaDistance + = deltaValue;
if(deltaDistance< 2)
{
deltaDistance = 1;
}
ScaleTransform scaleTransform = new ScaleTransform(deltaDistance,1);
canvas.RenderTransform = scaleTransform;
verticalLines.ForEach(x => {
x.RenderTransformOrigin = new Point(1,1);

x.RenderTransform = new ScaleTransform(1 / scaleTransform.ScaleX, 1 / scaleTransform.ScaleY);
});
canvas.Width = 60 * deltaDistance;
MyWidth = canvas.Width;
}

protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if(handler!= null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this,e);
}
}
}

公共类图
{
私有点来自;

public Point From
{
get {return from; }
set {from = value; }
}
private指向;

public Point To
{
get {return to; }
set {to = value; }
}

}
公共类MyLabel
{
public string ContentData {get;组; }

}

}



< ScrollViewer Name =scrollViewerHorizo​​ntalScrollBarVisibility = AutoMargin =10,10,0,10Padding =0,0,10,0
Width ={Binding RelativeSource = {RelativeSource TemplatedParent},Path = ActualWidth}
高度={Binding RelativeSource = {RelativeSource TemplatedParent},Path = ActualHeight}>
< Canvas x:Name =back_canvasWidth ={Binding MyWidth}Height =60

VerticalAlignment =TopHorizo​​ntalAlignment =LeftMargin =30, 30,10,20>
< Canvas.Background>
< DrawingBrush TileMode =TileViewport =0,0,30,30ViewportUnits =Absolute>

< DrawingBrush.Drawing>
< GeometryDrawing>
< GeometryDrawing.Geometry>
< RectangleGeometry Rect =0,0,30,30/>
< /GeometryDrawing.Geometry>
< GeometryDrawing.Pen>
<笔刷=灰色厚度=1/>
< /GeometryDrawing.Pen>
< / GeometryDrawing>
< /DrawingBrush.Drawing>
< / DrawingBrush>
< /Canvas.Background>
< ItemsControl ItemsSource ={Binding MyList}>
< ItemsControl.ItemsPanel>
< ItemsPanelTemplate>
< StackPanel Name =horizo​​ntalLabelsOrientation =Horizo​​ntal/>
< / ItemsPanelTemplate>
< /ItemsControl.ItemsPanel>
< ItemsControl.ItemTemplate>
< DataTemplate>
< TextBlock Text ={Binding ContentData}Canvas.Left =10Canvas.Top =0

Width =27
Height =30 FontSize =12
Margin =0,0,3,0>
< / TextBlock>
< / DataTemplate>
< /ItemsControl.ItemTemplate>
< / ItemsControl>

< ItemsControl ItemsSource ={Binding Lines}>
< ItemsControl.ItemsPanel>
< ItemsPanelTemplate>
< Canvas Height =30Margin =0,30,0,0Background =TransparentName =front_canvasClipToBounds =True
PreviewMouseWheel =OnPreviewMouseWheel
Width ={Binding MyWidth,UpdateSourceTrigger = PropertyChanged,Mode = TwoWay}
/>
< / ItemsPanelTemplate>
< /ItemsControl.ItemsPanel>

< ItemsControl.ItemTemplate>
< DataTemplate>
< Line X1 ={Binding From.X,Mode = TwoWay}Y1 ={Binding From.Y,Mode = TwoWay}Stretch =None
X2 ={Binding To .X,Mode = TwoWay}Y2 ={Binding To.Y,Mode = TwoWay}
Stroke =OrangeRedStrokeThickness =1

Loaded =Line_Loaded
/>
< / DataTemplate>
< /ItemsControl.ItemTemplate>

< / ItemsControl>


< / Canvas>



< / ScrollViewer>
< / Window>

解决方案

Zoombox·xceedsoftware / wpftoolkit Wiki·GitHub [ ^ ]

I am drawing a grid on canvas background. On this canvas, I am labeling the vertical lines of the grid which is drawn on canvas background. Then in the same canvas I have ItemsSource whose Panel is another Canvas and on that canvas I am drawing Line object using Points. Initially the the program is run the vertical lines of the grid are aligned with the points of Line object. The grid's vertical position is drawn at 30th position. And every point on the line is totally aligned to grid's vertical line. When the Mouse Wheel event is fired I want to zoom in the line object. I am using ScaleTransform for that purpose.

In the event handler I am changing the canvas width. Suppose I am using Scale transform with ScaleX equals to 4. This means the new canvas width will be equal to initial width *4. The point which located at 1 on canvas x axis will now be located at position 4 on canvas X axis. So, My 7th point will be at position 28.As we know that the vertical line of the grid is drawn at position 30. And my 8th point will be at position 32. Now I am clueless. I cannot select the position of vertical line of grid at run time. If 30 is selected initially it has to remain 30. While zooming in as I am increasing the width of canvas new Grids are drawn.Max zoom in condition is that there exists only 1 point in 1 grid rectangle. This means the vertical line will be drawn at position 30 so at 30th position the 1st point of line should appear.

What I have tried:

namespace CanvasWidthChecker
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        double scaleFactor = 1;
        double deltaDistance = 1;
        ulong totalSamples;
        const double maximumDeltaDistance = 30;
        double maximumScale = maximumDeltaDistance;
        List<Line> verticalLines = new List<Line>();

        private double initialWidth;

        public double InitialWidth
        {
            get { return initialWidth; }
            set { initialWidth = value; }
        }


        private double myWidth= 60;

        public double MyWidth
        {
            get { return myWidth; }
            set
            {
                myWidth = value;
                OnPropertyChanged("MyWidth");
            }
        }
        private void Line_Loaded(object sender, RoutedEventArgs e)
        {
            Line line = sender as Line;

            if (line.Y1 != line.Y2)
            {
                verticalLines.Add(line);
            }
        }
        private ObservableCollection<Graph> lines;

        public ObservableCollection<Graph> Lines
        {
            get { return lines; }
            set { lines = value; }
        }
        private ObservableCollection<MyLabel> myList;
        public ObservableCollection<MyLabel> MyList
        {
            get { return myList; }
            set
            {
                myList = value;
                OnPropertyChanged("MyList");
            }
        }

        private ulong samplecount;

        public ulong Samplecount
        {
            get { return samplecount; }
            set { samplecount = value; }
        }

        public MainWindow()
        {
            InitializeComponent();
            this.Samplecount = 60;
            this.InitialWidth = Samplecount;
            MyList = new ObservableCollection<MyLabel>();
            MyList.Add(new MyLabel() { ContentData = "0" });
            MyList.Add(new MyLabel() { ContentData = "30" });
            Lines = new ObservableCollection<Graph>();
            Lines.Add(new Graph() { From = new Point(0,22), To = new Point (18,22) });
            Lines.Add(new Graph() { From = new Point(18-0.5, 22), To = new Point(18-0.5, 7) });
            Lines.Add(new Graph() { From = new Point(18, 7), To = new Point(24, 7) });
            Lines.Add(new Graph() { From = new Point(24-0.5, 7), To = new Point(24-0.5, 22) });
            Lines.Add(new Graph() { From = new Point(24, 22), To = new Point(60, 22) }); // Samplecount  was 60

            DataContext = this;


        }

        private void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            Canvas canvas = (Canvas)sender;
            e.Handled = true;
            double deltaValue = (e.Delta > 0) ? 1 : -1;
            deltaDistance += deltaValue;
            if(deltaDistance<2)
            {
                deltaDistance = 1;
            }
            ScaleTransform scaleTransform = new ScaleTransform(deltaDistance, 1);
            canvas.RenderTransform = scaleTransform;
            verticalLines.ForEach(x => {
                x.RenderTransformOrigin = new Point(1, 1);

                x.RenderTransform = new ScaleTransform(1 / scaleTransform.ScaleX, 1 / scaleTransform.ScaleY);
            });
            canvas.Width = 60 * deltaDistance;
            MyWidth = canvas.Width;
        }

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                handler(this, e);
            }
        }
    }

    public class Graph
    {
        private Point from;

        public Point From
        {
            get { return from; }
            set { from = value; }
        }
        private Point to;

        public Point To
        {
            get { return to; }
            set { to = value; }
        }

    }
    public class MyLabel
    {
        public string ContentData { get; set; }

    }

}


<ScrollViewer  Name="scrollViewer" HorizontalScrollBarVisibility="Auto"  Margin="10,10,0,10" Padding="0,0,10,0"
            Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualWidth}"
                       Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight}"     >
        <Canvas  x:Name="back_canvas"  Width="{Binding MyWidth}" Height="60" 

              VerticalAlignment="Top" HorizontalAlignment="Left"  Margin="30,30,10,20"   >
            <Canvas.Background>
                <DrawingBrush TileMode="Tile" Viewport="0,0,30,30"  ViewportUnits="Absolute">

                    <DrawingBrush.Drawing>
                        <GeometryDrawing>
                            <GeometryDrawing.Geometry>
                                <RectangleGeometry Rect="0,0,30,30"/>
                            </GeometryDrawing.Geometry>
                            <GeometryDrawing.Pen>
                                <Pen Brush="Gray" Thickness="1"/>
                            </GeometryDrawing.Pen>
                        </GeometryDrawing>
                    </DrawingBrush.Drawing>
                </DrawingBrush>
            </Canvas.Background>
            <ItemsControl ItemsSource="{Binding MyList}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Name="horizontalLabels" Orientation="Horizontal"/>
                   </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock      Text="{Binding ContentData}"  Canvas.Left="10" Canvas.Top="0"

                                         Width="27" 
                                         Height="30"  FontSize="12"
                                         Margin="0,0,3,0">
                        </TextBlock>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>

            <ItemsControl ItemsSource="{Binding Lines}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas  Height="30" Margin="0,30,0,0"  Background="Transparent"  Name="front_canvas" ClipToBounds="True" 
                                    PreviewMouseWheel="OnPreviewMouseWheel"
                                      Width="{Binding MyWidth, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" 
                                      />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>

                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Line   X1="{Binding From.X , Mode=TwoWay}" Y1="{Binding From.Y, Mode=TwoWay}" Stretch="None"
                            X2="{Binding To.X, Mode=TwoWay}" Y2="{Binding To.Y, Mode=TwoWay}" 
                            Stroke="OrangeRed" StrokeThickness="1" 

                                  Loaded="Line_Loaded"
                            />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>

            </ItemsControl>


            </Canvas>



    </ScrollViewer>
</Window>

解决方案

Zoombox · xceedsoftware/wpftoolkit Wiki · GitHub[^]


这篇关于将网格垂直线与WPF中的线对象对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆