hamid18 Ответов: 1

Выравнивание вертикальной линии сетки с объектом point of line в WPF


Я рисую сетку на фоне холста. На этом холсте я обозначаю вертикальные линии сетки, которая рисуется на фоне холста. Затем на том же холсте у меня есть ItemsSource, панель которого является другим холстом, и на этом холсте я рисую линейный объект, используя точки. Изначально при запуске программы вертикальные линии сетки выравниваются с точками линейного объекта. Вертикальное положение сетки рисуется в 30-й позиции. И каждая точка на линии полностью выровнена по вертикальной линии сетки. Когда запускается событие колеса мыши, я хочу увеличить масштаб линейного объекта. Для этой цели я использую ScaleTransform.

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.

Что я уже пробовал:

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>

1 Ответов

Рейтинг:
0

hamid18

Спасибо, что поделились ссылкой. Я знаю, что для увеличения масштаба мне нужно использовать ScaleTransform. e.g
ScaleTransform scaleTransform = новая ScaleTransform(4, 1);

холст.RenderTransform = scaleTransform;
холст.Ширина = 60 * 4;
MyWidth = холст.Ширина;
Когда я делаю это, начальная ширина увеличивается в 4 раза, и каждая точка на холсте умножается на 4 вдоль оси X. Это означает, что в положении 28 вдоль оси x я получу 7-е значение отсчета выборок. Без увеличения эта точка присутствовала в позиции 7. Теперь 8-й отсчет выборки будет идти в 32 позиции. Но вертикальная линия будет проведена в положении 30. И мне нужно дискретное значение отсчета выборок в позиции 30. Я не хочу ничего подобного 7.5 или 7.2 и т. д. Потому что значения отсчета выборок всегда дискретны.