Zoom Image, используя WPF MVVM, переместит элементы управления верхнего слоя.Как это можно исправить на время увеличения изображения? - PullRequest
0 голосов
/ 29 января 2019

В настоящее время я работаю над проектом обработки изображений, где у меня есть один экран просмотра, на котором я устанавливаю изображение в контейнер изображений, а поверх изображения все четыре угла имеют метаданные, которые являются фиксированными.Означает, что при увеличении / уменьшении изображения верхний контент останется в фиксированном положении и не будет двигаться.Это мое требование.

Теперь я установил весь контент динамически, используя панель стека, и все метаданные останутся на фиксированной позиции, кроме нижней правой позиции, которая будет перемещаться при увеличении / уменьшении изображения.

ниже приведен справочный снимок экрана, где красная метка показывает, что метаданные будут перемещены и скрыты с правой стороны.

Image container

Вот код для правого нижнего содержимого

public async Task<ScrollViewer> CreateNewScrollViewer(ImageInfo item)
    {
        ScrollViewer scrollViewerObj = new ScrollViewer();

        byte[] rawData;
        try
        {

            //this will update the values of any older sharpness data to 5
            if (item.AnnotationSchemaVersion != null && item.AnnotationSchemaVersion.Equals("1.0", StringComparison.InvariantCulture))
            {
                item.AdjustmentValue.Sharpness = item.BytePerPixel == 3 ? _samSettingsManager.GetTrueColorSharpnessDefaultValue() : _samSettingsManager.GetSingleColorSharpnessDefaultValue();
                var saveSharpness = new Task(() => this.UpdateImageAnalysis(item));
                saveSharpness.Start();
            }


            scrollViewerObj.SetValue(AutomationProperties.AutomationIdProperty, "ReviewImageDetailView_ScrollViewer");
            scrollViewerObj.SetValue(AutomationProperties.NameProperty, "ReviewImageDetailView_ScrollViewer");

            scrollViewerObj.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
            scrollViewerObj.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
            scrollViewerObj.Margin = new Thickness(5, 5, 5, 5);
            scrollViewerObj.Focusable = true;
            scrollViewerObj.SizeChanged += new SizeChangedEventHandler(ScrollViewerSizeChanged);

            Point? fixationTarget = null;
            Point? foveaXY = null;
            Point? onhXY = null;
            FixationType fixationMode = FixationType.Internal;
            bool performDistortionCorrection = false;
            // Provide fixation values only for WF and Non-External(Non-AnteriorSegment) scans, as distortion correction shall only be applied to WF and Non-External(Non-AnteriorSegment) images.
            // All composite UWF/Montage/Auto-Montage images will be distortion corrected (Montage algorithm generates distortion corrected image)
            if (Convert.ToInt32(item.FOV, CultureInfo.InvariantCulture) == FOVConstants.Widefield &&
                item.ExamMode != ExamModes.AnteriorSegment && SAMConstants.SAMExamSourceUID == item.ExamSourceUID)
            {
                fixationTarget = item.FixationXY;
                foveaXY = item.FoveaXY;
                onhXY = item.ONHXY;
                fixationMode = item.FixationMode;
                performDistortionCorrection = true;
            }
            //bool isOD = item.Laterality == "OD" ? true : false;


            string imageCacheFilePath = _imageCacheFilePath;
            string imageFileName = System.IO.Path.GetFileName(item.ImagePath);


            //creates the image cache folder if it doesn't exist
            if (!Directory.Exists(imageCacheFilePath))
                Directory.CreateDirectory(imageCacheFilePath);

            ImageContainer imageObj = new ImageContainer(_pixelBufferSize);

            await Task.Run(() =>
            {
                imageObj.Initialize(item.ImagePath, item.ImageCompressionType,

item.ImageWidth, item.ImageHeight, item.BytePerPixel, item.ExamSourceUID, item.Laterality, imageCacheFilePath, _pixelBufferSize, fixationTarget, foveaXY, item.ProjectedXMin, item.ProaxX .MY.ProjectedYMin, executeDistortionCorrection, onhXY, fixationMode, item.ONHIdentificationMode);

            });


            imageObj.InitializeZoomValues(((int)ActualHeight - 40) / 4, ((int)ActualWidth - 40) / 4);

            PyramidTools.PyramidImageProcessing processImage = new PyramidTools.PyramidImageProcessing();

            //Sets up the pyramid 
            if (!System.IO.File.Exists(imageCacheFilePath + imageFileName + ExtensionConstants.Raw) || (!System.IO.File.Exists(imageCacheFilePath + imageFileName + ExtensionConstants.Text) && SAMConstants.SAMExamSourceUID == imageObj.ExamSourceUID))
            {
                rawData = imageObj.ImageDataObj.GetData();
                if (rawData != null)
                {
                    processImage.CreatePyramidForGivenImage(rawData, item.BytePerPixel, (int)imageObj.ImageZoom.LowestZoomPercentage, imageFileName, imageObj.ImageDataObj.Width, imageObj.ImageDataObj.Height, imageCacheFilePath);
                }
            }
            else if (!processImage.IsPyramidCreated(imageCacheFilePath + imageFileName, (int)imageObj.ImageZoom.LowestZoomPercentage))
            {
                rawData = File.ReadAllBytes(imageCacheFilePath + imageFileName + ExtensionConstants.Raw);
                if (rawData != null)
                {
                    processImage.CreatePyramidForGivenImage(rawData, item.BytePerPixel, (int)imageObj.ImageZoom.LowestZoomPercentage, imageFileName, imageObj.ImageDataObj.Width, imageObj.ImageDataObj.Height, imageCacheFilePath);
                }
            }

            //  For image sharpness
            imageObj.ImageProcessing = imageProcessing;
            imageObj.TrueColorSharpnessRadius = _trueColorSharpnessRadius;
            imageObj.TrueColorSharpnessMinAmount = _trueColorSharpnessMinAmount;
            imageObj.TrueColorSharpnessMaxAmount = _trueColorSharpnessMaxAmount;
            imageObj.TrueColorSharpnessResizeFactor = _trueColorSharpnessResizeFactor;
            imageObj.SingleColorSharpnessRadius = _singleColorSharpnessRadius;
            imageObj.SingleColorSharpnessMinAmount = _singleColorSharpnessMinAmount;
            imageObj.SingleColorSharpnessMaxAmount = _singleColorSharpnessMaxAmount;
            imageObj.SingleColorSharpnessResizeFactor = _singleColorSharpnessResizeFactor;
            imageObj.TrueColorSharpnessFactor = _trueColorSharpnessFactor;
            imageObj.SingleColorSharpnessFactor = _singleColorSharpnessFactor;

            imageObj.IsConstituteImage = item.IsConstituteImage;

            imageObj.FOV = item.FOV;
            imageObj.SelectedChannel = ChannelTypes.TrueColorChannel;
            imageObj.TonalOptimizedValues = new Tonal(128, 128, 128);
            imageObj.SetValue(AutomationProperties.AutomationIdProperty, "ReviewImageDetailView_ImageContainer");
            imageObj.SetValue(AutomationProperties.NameProperty, "ReviewImageDetailView_ImageContainer");

            BitmapImage logo = new BitmapImage();
            logo.BeginInit();
            logo.UriSource = new Uri("pack://application:,,,/SAMProduction.FundusImageDisplay;component/Images/RotateBlue.png");
            logo.EndInit();

            imageObj.ImageRotationShow = new System.Windows.Controls.Image();
            imageObj.ImageRotationShow.Source = logo;
            imageObj.ImageRotationShow.SetValue(AutomationProperties.AutomationIdProperty, "ReviewImageDetailView_180DegreeIcon");
            imageObj.ImageRotationShow.SetValue(AutomationProperties.NameProperty, "ReviewImageDetailView_180DegreeIcon");
            //imageObj.ImageRotationShow.SetResourceReference(Canvas.BackgroundProperty, "180DegreeIcon");
            imageObj.ImageRotationShow.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
            imageObj.ImageRotationShow.VerticalAlignment = System.Windows.VerticalAlignment.Top;
            imageObj.ImageRotationShow.Visibility = System.Windows.Visibility.Collapsed;
            imageObj.ImageRotationShow.Width = 30;
            imageObj.ImageRotationShow.Height = 30;
            imageObj.ImageRotationShow.Margin = new Thickness(0, 10, 0, 0);

            imageObj.ImageFrameNoMessage = item.ImageFrameNoMessage;
            Style textBlockStyle = this.TryFindResource("TextWhite16") as Style;

            #region Top Left Panel Information
            StackPanel topLeftPanelInfo = new StackPanel();
            topLeftPanelInfo.Width = 160;
            topLeftPanelInfo.Name = "TopLeftPanel";
            topLeftPanelInfo.Uid = "TopLeftPanel";
            topLeftPanelInfo.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
            topLeftPanelInfo.VerticalAlignment = System.Windows.VerticalAlignment.Top;
            topLeftPanelInfo.Margin = new Thickness(10, 5, 0, 0);

            UpdateTopLeftPanel(item, imageObj, topLeftPanelInfo, textBlockStyle);
            #endregion

            #region Bottom Left Panel Information
            StackPanel bottomLeftPanelInfo = new StackPanel();
            bottomLeftPanelInfo.Name = "BottomLeftPanel";
            bottomLeftPanelInfo.Uid = "BottomLeftPanel";
            bottomLeftPanelInfo.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
            bottomLeftPanelInfo.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
            bottomLeftPanelInfo.Margin = new Thickness(10, 0, 0, 5);

            UpdateBottomLeftPanel(item, imageObj, bottomLeftPanelInfo, textBlockStyle);
            #endregion

            #region Bottom Right Panel Information
            StackPanel bottomRightPanelInfo = new StackPanel();
            bottomRightPanelInfo.Name = "BottomRightPanel";
            bottomRightPanelInfo.Uid = "BottomRightPanel";
            bottomRightPanelInfo.SetValue(AutomationProperties.AutomationIdProperty, "ReviewImageDetailView_BottomRightPanelInfo");
            bottomRightPanelInfo.SetValue(AutomationProperties.NameProperty, "ReviewImageDetailView_BottomRightPanelInfo");
            bottomRightPanelInfo.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
            bottomRightPanelInfo.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
            bottomRightPanelInfo.Margin = new Thickness(0, 0, 10, 5);

            UpdateBottomRightPanel(item, imageObj, bottomRightPanelInfo, textBlockStyle);
            #endregion

            #region Top Right Panel Information
            StackPanel topRightPanelInfo = new StackPanel();
            topRightPanelInfo.Name = "TopRightPanel";
            topRightPanelInfo.Uid = "TopRightPanel";
            topRightPanelInfo.SetValue(AutomationProperties.AutomationIdProperty, "ReviewImageDetailView_TopRightPanelInfo");
            topRightPanelInfo.SetValue(AutomationProperties.NameProperty, "ReviewImageDetailView_TopRightPanelInfo");
            topRightPanelInfo.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
            topRightPanelInfo.VerticalAlignment = System.Windows.VerticalAlignment.Top;
            topRightPanelInfo.Margin = new Thickness(0, 5, 10, 0);

            UpdateTopRightPanel(item, imageObj, topRightPanelInfo, textBlockStyle);
            #endregion

            Grid gridObj = new Grid() { ClipToBounds = true };//

            gridObj.SetValue(AutomationProperties.AutomationIdProperty, "ReviewImageDetailView_Grid");
            gridObj.SetValue(AutomationProperties.NameProperty, "ReviewImageDetailView_Grid");

            gridObj.Children.Add(imageObj);

            if (topLeftPanelInfo != null)
            {
                gridObj.Children.Add(topLeftPanelInfo);
            }
            if (bottomLeftPanelInfo != null)
            {
                gridObj.Children.Add(bottomLeftPanelInfo);
            }
            if (topRightPanelInfo != null)
            {
                gridObj.Children.Add(topRightPanelInfo);
            }
            if (bottomRightPanelInfo != null)
            {
                gridObj.Children.Add(bottomRightPanelInfo);
            }

            gridObj.Children.Add(imageObj.SelectedBorder);
            gridObj.Children.Add(imageObj.ImageRotationShow);
            gridObj.Children.Add(imageObj.OverlayGrid);

            imageObj.OverlayGrid.MouseLeftButtonUp += OverlayGrid_MouseLeftButtonUp;
            imageObj.OverlayGrid.MouseMove += OverlayGrid_MouseMove;
            imageObj.OverlayGrid.MouseLeftButtonDown += OverlayGrid_MouseLeftButtonDown;
            imageObj.OverlayGrid.PreviewMouseRightButtonDown += OverlayGrid_PreviewMouseRightButtonDown;
            imageObj.OverlayGrid.PreviewMouseRightButtonUp += OverlayGrid_PreviewMouseRightButtonUp;

            scrollViewerObj.Content = gridObj;

            // This binding required to align image properly when it is loading.
            Binding HeightBinding = new Binding();
            RelativeSource relativeheightSource = new RelativeSource();
            relativeheightSource.Mode = RelativeSourceMode.FindAncestor;
            relativeheightSource.AncestorType = typeof(ScrollViewer);
            HeightBinding.RelativeSource = relativeheightSource;
            HeightBinding.Path = new PropertyPath("ActualHeight");
            HeightBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            HeightBinding.Mode = BindingMode.OneWay;
            imageObj.SetBinding(System.Windows.Controls.Image.HeightProperty, HeightBinding);

            Binding WidthBinding = new Binding();
            RelativeSource relativeWidthSource = new RelativeSource();
            relativeWidthSource.Mode = RelativeSourceMode.FindAncestor;
            relativeWidthSource.AncestorType = typeof(ScrollViewer);
            WidthBinding.RelativeSource = relativeWidthSource;
            WidthBinding.Path = new PropertyPath("ActualWidth");
            WidthBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            WidthBinding.Mode = BindingMode.OneWay;
            imageObj.SetBinding(System.Windows.Controls.Image.WidthProperty, WidthBinding);

            imageObj.ImageSourceChanged += this.ImageObj_ImageSourceChanged;

            imageObj.ZoomValueChanged += this.ImageObj_ZoomValueChanged;

            scrollViewerObj.AllowDrop = true;
            scrollViewerObj.Drop += ScrollViewer_Drop;

            imageObj.ContainerTonalValueChanged += ImageObj_ContainerTonalValueChanged;

            // Previously MouseLeftButtonDown event was used. 
            // Change set no 141851 has change code of CreateNewScrollViewer(). He set Scrollviewer’s Focable property to true.
            // It is required to set focusable true for that change set.
            // In ScrollViewer's original code (.net code) it is handling event (e.Handled = true) if it can get focus.
            // So side effect of 141851 change set is MouseLeftButtonDown event of scrollviewer do not get call when mouse down on it.
            // So it misbehaves.
            // So here PreviewMouseLeftButtonDown event used.

            scrollViewerObj.PreviewMouseLeftButtonDown += ScrollViewerObj_PreviewMouseLeftButtonDown;
            scrollViewerObj.MouseLeftButtonUp += this.ScrollViewerObj_MouseLeftButtonUp;
            scrollViewerObj.PreviewMouseWheel += ScrollViewerObj_PreviewMouseWheel;

            // No need to handle this event
            //imageObj.SizeChanged += this.ImageObj_SizeChanged;
            imageObj.MouseMove += this.ImageObj_MouseMove;
            imageObj.MouseLeftButtonDown += this.ImageObj_MouseLeftButtonDown;
            imageObj.MouseLeftButtonUp += this.ImageObj_MouseLeftButtonUp;

            gridObj.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
            gridObj.VerticalAlignment = System.Windows.VerticalAlignment.Center;

            //It is not necessary to initalize the data
            imageObj.ImageID = item.ImageId;
            //imageObj.ImagePath = item.ImagePath;

            if (imageObj.ExamSourceUID == SAMConstants.SAMExamSourceUID &&
                imageObj.ExamMode != ExamModes.AnteriorSegment)
                imageObj.OverlayGrid.IsHitTestVisible = IsOverlayGridEnable;
            else
                imageObj.OverlayGrid.IsHitTestVisible = false;
            // imageObj.OverlayGrid.IsHitTestVisible = IsOverlayGridEnable;
            //imageObj.ImageSource = imageObj.ImageDataObj;

            scrollViewerObj.ContextMenu = CreateContextMenu(scrollViewerObj, imageObj); // set contextmenu
        }
        catch (Exception ex)
        {
            _services.Logger.Log(LogLevel.Error, "SAMProduction.FundusImageDisplay", "ImageEditViewerBase", "CreateNewScrollViewer: Error occurred while creating new scrollviewer. : " + ex);
        }
        finally
        {
            rawData = null;
        }
        return scrollViewerObj;
    }

Пожалуйста, позвольте мне помочь разрешить перемещенный контент на верхнем слое изображения, если это возможно.Заранее спасибо.

1 Ответ

0 голосов
/ 29 января 2019

Я считаю создание представлений в коде очень нечитаемым, поэтому вот как этого добиться в XAML:

<Grid>
  <Image .../> // or whatever custom control you use to allow zoom

  <StackPanel Name="TopLeft HorizontalAligment="Left" VerticalAligment="Top">
       <contente: labels etc ../>
  </StackPanel>

  ...
  <StackPanel Name="BottomRight" HorizontalAligment="Right" VerticalAligment="Bottom">
       <contente: labels etc ../>
  </StackPanel>

</Grid>

Хитрость заключается в том, чтобы обернуть все, что вы хотите, в одном месте и / или наложитьв сетке.Если элементы StackPanels расположены после содержимого «Изображение в сетке», их z-индекс будет выше, и они будут отображаться поверх изображения.

Элемент управления по умолчанию будет растянут на всю сетку, поэтому выследует манипулировать масштабом с его содержимым, а не с его размером.Если это проблематично, просто оберните элемент управления изображением с помощью другой панели или, в лучшем случае, пользовательского элемента управления UserControl и устраните проблемы с размером.

Благодаря сетке StackPanels будет привязываться к углам независимо от размераи форма сетки.

Кроме того, вы использовали тег MVVM, и ваш код - почти учебник не MVVM.

Возможно, это поможет вам переписать ваш код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...