我必须编写一个能够同时放大和缩小两个不同图层的应用程序。
背景图层包含一个在缩放过程中始终居中的图像。但是,第二层基于父容器的上边缘。
这是我的XAML代码:
<ScrollViewer Visibility="{Binding LeerformularIsVisible}" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Grid>
<Image x:Name="DZBackgroundImage" Source="{Binding DZGridBackground}" Stretch="None" />
<DataGrid ColumnWidth="7" MinColumnWidth="7" RowHeight="15" BorderBrush="{x:Null}" AutoGenerateColumns="True" CanUserAddRows="False"
Visibility="{Binding GridIsVisible}" ItemsSource="{Binding DPGridCR}" Margin="5,50,70,0" Background="Transparent" RowBackground="Transparent"
HeadersVisibility="None" SelectionUnit="Cell" CanUserResizeRows="False" HorizontalGridLinesBrush="{Binding LineBrush}" VerticalGridLinesBrush="{Binding LineBrush}">
<i:Interaction.Behaviors>
<ViewModel:IgnoreMouseWheelBehavior />
</i:Interaction.Behaviors>
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#325EB226" />
<Setter Property="BorderBrush" Value="#325EB226" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding AddFieldDefinitionCommand}" Header="Feld hinterlegen" Icon="pack://application:,,,/Images/Designer/field.png" />
<MenuItem Command="{Binding AddFunctionCommand}" Header="Funktion hinterlegen" Icon="pack://application:,,,/Images/Designer/function.png" />
<MenuItem Command="{Binding RemoveFieldDefinitionCommand}" Header="Aktuelle Felddefinition entfernen" Icon="pack://application:,,,/Images/Designer/remove_field.png" />
<MenuItem Command="{Binding CutCommand}" Header="Ausschneiden" Icon="pack://application:,,,/Images/Zwischenablage/FI_Ausschneiden_16x16.png" />
<MenuItem Command="{Binding CopyCommand}" Header="Kopieren" Icon="pack://application:,,,/Images/Zwischenablage/FI_Kopieren_16x16.png" />
<MenuItem Command="{Binding PasteCommand}" Header="Einfügen" Icon="pack://application:,,,/Images/Zwischenablage/FI_Einfuegen_16x16.png" />
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
<Grid.LayoutTransform>
<ScaleTransform ScaleX="{Binding ZoomFactor}" ScaleY="{Binding ZoomFactor}" />
</Grid.LayoutTransform>
</Grid>
</ScrollViewer>
我从我的视图模型中获取了ZoomFactor绑定的值。
我的目标是同时缩放两个图层并重叠。
提前致谢。
修改 这是整个XAML文件。
<UserControl x:Class="Controls.DZLeerformularGrid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ViewModel="clr-namespace:ViewModel;assembly=ViewModel"
xmlns:Behaviors="clr-namespace:ViewModel.Behaviors;assembly=ViewModel"
xmlns:Extension="clr-namespace:Controls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
x:Name="DZLeerformularGridControl">
<ScrollViewer Behaviors:AdvancedZooming.KeepInCenter="true" Visibility="{Binding LeerformularIsVisible}" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Viewbox RenderTransformOrigin="0.5, 0.5" Stretch="Uniform">
<Grid>
<Image x:Name="DZBackgroundImage" Source="{Binding DZGridBackground}" Stretch="None" />
<DataGrid ColumnWidth="7" MinColumnWidth="7" RowHeight="15" BorderBrush="{x:Null}" AutoGenerateColumns="True" CanUserAddRows="False"
Visibility="{Binding GridIsVisible}" ItemsSource="{Binding DPGridCR}" Margin="5,50,70,0" Background="Transparent" RowBackground="Transparent"
HeadersVisibility="None" SelectionUnit="Cell" CanUserResizeRows="False" HorizontalGridLinesBrush="{Binding LineBrush}" VerticalGridLinesBrush="{Binding LineBrush}">
<i:Interaction.Behaviors>
<Behaviors:IgnoreMouseWheelBehavior />
</i:Interaction.Behaviors>
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#325EB226" />
<Setter Property="BorderBrush" Value="#325EB226" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding AddFieldDefinitionCommand}" Header="Feld hinterlegen" Icon="pack://application:,,,/Images/Designer/field.png" />
<MenuItem Command="{Binding AddFunctionCommand}" Header="Funktion hinterlegen" Icon="pack://application:,,,/Images/Designer/FI_Taschenmesser_16x16.png" />
<MenuItem Command="{Binding RemoveFieldDefinitionCommand}" Header="Aktuelle Felddefinition entfernen" Icon="pack://application:,,,/Images/Designer/remove_field.png" />
<MenuItem Command="{Binding CutCommand}" Header="Ausschneiden" Icon="pack://application:,,,/Images/Zwischenablage/FI_Ausschneiden_16x16.png" />
<MenuItem Command="{Binding CopyCommand}" Header="Kopieren" Icon="pack://application:,,,/Images/Zwischenablage/FI_Kopieren_16x16.png" />
<MenuItem Command="{Binding PasteCommand}" Header="Einfügen" Icon="pack://application:,,,/Images/Zwischenablage/FI_Einfuegen_16x16.png" />
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
</Grid>
<Viewbox.RenderTransform>
<ScaleTransform ScaleX="{Binding ZoomFactor}" ScaleY="{Binding ZoomFactor}" />
</Viewbox.RenderTransform>
</Viewbox>
</ScrollViewer>
</UserControl>
以下是我的ViewModel的C#代码:
using System.Collections.Generic;
using System.Data;
using System.Windows.Media;
using System.Windows.Input;
using ViewModelBase;
using System.Windows;
namespace ViewModel
{
public class DZLeerformularGridViewModel : ViewModelBase.ViewModelBase
{
#region Fields
#region Command Fields
private RelayCommand addFieldDefinition;
private RelayCommand removeFieldDefinition;
private RelayCommand addFunction;
private RelayCommand cutCommand;
private RelayCommand copyCommand;
private RelayCommand pasteCommand;
#endregion
private string leerformularIsVisible;
private string dzGridBackground;
private string gridIsVisible;
private SolidColorBrush lineBrush;
private DataTable dpGridCR;
private double zoomFactor;
#endregion
public DZLeerformularGridViewModel()
{
LineBrush = Brushes.LightGray;
}
#region Properties
public string LeerformularIsVisible
{
get { return leerformularIsVisible; }
set
{
if (leerformularIsVisible != value)
{
leerformularIsVisible = value;
OnPropertyChanged("LeerformularIsVisible");
}
}
}
public string DZGridBackground
{
get { return dzGridBackground; }
set
{
if (dzGridBackground != value)
{
System.Drawing.Image img = System.Drawing.Image.FromFile(value);
if (img.Height > img.Width)
generateColsAndRows(94, 70); // DIN A4 Hochformat
else
generateColsAndRows(70, 94); // DIN A4 Querformat
dzGridBackground = value;
OnPropertyChanged("DZGridBackground");
}
}
}
public string GridIsVisible
{
get { return gridIsVisible; }
set
{
if (gridIsVisible != value)
{
gridIsVisible = value;
OnPropertyChanged("GridIsVisible");
}
}
}
public SolidColorBrush LineBrush
{
get { return lineBrush; }
set
{
if (lineBrush != value)
{
if (!value.Equals(Brushes.LightGray) || !value.Equals(Brushes.Gray) || ! value.Equals(Brushes.LightSlateGray) || !value.Equals(Brushes.SlateGray) ||
!value.Equals(Brushes.Black) || !value.Equals(Brushes.Red) || !value.Equals(Brushes.DarkGray))
lineBrush = Brushes.LightGray;
else
lineBrush = value;
OnPropertyChanged("LineBrush");
}
}
}
public DataTable DPGridCR
{
get { return dpGridCR; }
set
{
if (dpGridCR != value)
{
dpGridCR = value;
OnPropertyChanged("DPGridCR");
}
}
}
public double ZoomFactor
{
get { return zoomFactor; }
set
{
if (zoomFactor != value)
{
zoomFactor = value;
OnPropertyChanged("ZoomFactor");
}
}
}
#endregion
#region Command Properties
public ICommand AddFieldDefinitionCommand
{
get
{
if (addFieldDefinition == null)
addFieldDefinition = new RelayCommand(p => ExecuteAddFieldDefinitionCommand());
return addFieldDefinition;
}
}
public ICommand RemoveFieldDefinitionCommand
{
get
{
if (removeFieldDefinition == null)
removeFieldDefinition = new RelayCommand(p => ExecuteRemoveFieldDefinitionCommand());
return removeFieldDefinition;
}
}
public ICommand AddFunctionCommand
{
get
{
if (addFunction == null)
addFunction = new RelayCommand(p => ExecuteAddFunctionCommand());
return addFunction;
}
}
public ICommand CutCommand
{
get
{
if (cutCommand == null)
cutCommand = new RelayCommand(p => ExecuteCutCommand());
return cutCommand;
}
}
public ICommand CopyCommand
{
get
{
if (copyCommand == null)
copyCommand = new RelayCommand(p => ExecuteCopyCommand());
return copyCommand;
}
}
public ICommand PasteCommand
{
get
{
if (pasteCommand == null)
pasteCommand = new RelayCommand(p => ExecutePasteCommand());
return pasteCommand;
}
}
#endregion
#region Methods
private void generateColsAndRows(int amountOfCols, int amountOfRows)
{
DataTable table = new DataTable();
List<DataColumn> cols = new List<DataColumn>();
for (int i = 0; i < amountOfCols; i++)
{
DataColumn column = new DataColumn();
column.ReadOnly = true;
table.Columns.Add(column);
cols.Add(column);
}
for (int i = 0; i < amountOfRows; i++)
{
DataRow row = table.NewRow();
foreach (DataColumn col in cols)
row[col] = " ";
table.Rows.Add(row);
}
DPGridCR = table;
}
#endregion
#region Command Methods
private void ExecuteAddFieldDefinitionCommand()
{
MessageBox.Show("Add field definition");
}
private void ExecuteRemoveFieldDefinitionCommand()
{
MessageBox.Show("Remove field definition");
}
private void ExecuteAddFunctionCommand()
{
MessageBox.Show("Add function");
}
private void ExecuteCutCommand()
{
MessageBox.Show("Cut");
}
private void ExecuteCopyCommand()
{
MessageBox.Show("Copy");
}
private void ExecutePasteCommand()
{
MessageBox.Show("Paste");
}
#endregion
}
}
放大图像时,不会出现水平滚动条。当我缩小图像时,垂直滚动条不会消失。这种效果是由RenderTransform
的使用造成的。如果我使用LayoutTransform
,则DataGrid
会绑定到Grid
或ViewBox
的上边缘。我怎么能解决这个问题?在我看来,我需要LayoutTransform
和RenderTransfrom
的组合。
答案 0 :(得分:1)
您可以创建附加行为并将其附加到滚动查看器。因此,该行为将检测内容大小的变化,并将内容保持在滚动查看器的中心
这里是我之前回答的类似问题的链接,您可以在答案中找到该行为类
Maintain scrollviewer's relative scrollbar offset when resizing child
所以从上面的链接中的答案中取出AdvancedZooming类,并将以下属性设置为滚动查看器
<ScrollViewer Visibility="{Binding LeerformularIsVisible}"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
l:AdvancedZooming.KeepInCenter="True">
其中l:指项目的命名空间。这就是在缩放时将内容保持在中心所需的一切
修改强>
<ScrollViewer Visibility="{Binding LeerformularIsVisible}"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
l:AdvancedZooming.KeepInCenter="True">
<Viewbox>
<Grid>
<Image x:Name="DZBackgroundImage"
Source="{Binding DZGridBackground}"
Stretch="None" />
<DataGrid>
...
</DataGrid>
</Grid>
<Viewbox.LayoutTransform>
<ScaleTransform ScaleX="{Binding ZoomFactor}"
ScaleY="{Binding ZoomFactor}" />
</Viewbox.LayoutTransform>
</Viewbox>
</ScrollViewer>
如果您发现datagrid或图片的大小太小或太大,请尝试调整网格,图片或数据网格的宽度/高度,视图框会相应缩放