C# XAML相当于CSS中的对象位置
我正在开发一个WPF应用程序,它显示一个项目列表,每个项目都有一个与之关联的小图像。我从API接收图像url和由0-1之间的两个数字表示的焦点。 web应用程序只需将这些数字乘以100,并使用它们设置对象位置CSS属性,如下所示:C# XAML相当于CSS中的对象位置,c#,wpf,css,xaml,C#,Wpf,Css,Xaml,我正在开发一个WPF应用程序,它显示一个项目列表,每个项目都有一个与之关联的小图像。我从API接收图像url和由0-1之间的两个数字表示的焦点。 web应用程序只需将这些数字乘以100,并使用它们设置对象位置CSS属性,如下所示: focusPoints: 0.9/0.5 变成 object-position: 90% 50%; 我的问题是如何在WPF中使用它?并没有类似于对象位置的属性,尽管我认为我只需要使用Margin,但它似乎并没有那个么简单。 我给你举个例子。假设我有一张人脸的照片,
focusPoints: 0.9/0.5
变成
object-position: 90% 50%;
我的问题是如何在WPF中使用它?并没有类似于对象位置的属性,尽管我认为我只需要使用Margin,但它似乎并没有那个么简单。
我给你举个例子。假设我有一张人脸的照片,但是这张脸不是以图像为中心,而是在右边。如果裁剪图像,则将裁剪面,但如果在面上设置焦点,则将从左侧裁剪图像,而不是从每条边剪切。这就是焦点的使用方式,在CSS中只使用对象位置,但在XAML中,我想我必须做一些数学计算,以确定什么是边距或画布。上/左。
此外,还介绍了如何在图像中设置焦点。CSS对象位置的工作原理
它将img html元素的宽度/高度与实际图片的宽度/高度进行比较。这些差异被认为是“100%”。因此,如果容器(img元素)的宽度为100px,图片的宽度为160px,则差值为60px,即“100%”。如果我们将“水平对象位置”值设置为50%,它将在容器内向左移动图片30px(60px的50%),从而使图片水平居中
WPF控制
在画布中操纵图像的自定义控件
[TemplatePart(Name = ImagePart, Type = typeof(Image))]
[TemplatePart(Name = CanvasPart, Type = typeof(Canvas))]
public class PositionableImage : Control
{
private const string ImagePart = "PART_Image";
private const string CanvasPart = "PART_Canvas";
static PositionableImage()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(PositionableImage),
new FrameworkPropertyMetadata(typeof(PositionableImage)));
}
public string Source
{
get { return (string)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
public static readonly DependencyProperty SourceProperty = DependencyProperty.Register(
"Source",
typeof(string),
typeof(PositionableImage),
new PropertyMetadata(string.Empty));
public double HorizontalPosition
{
get { return (double)GetValue(HorizontalPositionProperty); }
set { SetValue(HorizontalPositionProperty, value); }
}
public static readonly DependencyProperty HorizontalPositionProperty = DependencyProperty.Register(
"HorizontalPosition",
typeof(double),
typeof(PositionableImage),
new PropertyMetadata(0d, OnHorizontalPositionChanged));
private static void OnHorizontalPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
PositionableImage pi = d as PositionableImage;
if (pi == null) return;
if (!double.TryParse(e.NewValue.ToString(), out double newPosition)) return;
pi.UpadateHorizontalPosition(newPosition);
}
public double VerticalPosition
{
get { return (double)GetValue(VerticalPositionProperty); }
set { SetValue(VerticalPositionProperty, value); }
}
public static readonly DependencyProperty VerticalPositionProperty = DependencyProperty.Register(
"VerticalPosition",
typeof(double),
typeof(PositionableImage),
new PropertyMetadata(0d, OnVerticalPositionSizeChanged));
private static void OnVerticalPositionSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
PositionableImage pi = d as PositionableImage;
if (pi == null) return;
if (!double.TryParse(e.NewValue.ToString(), out double newPosition)) return;
pi.UpdateVerticalPosition(newPosition);
}
private Image image;
private Canvas canvas;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (this.canvas != null)
this.canvas.SizeChanged -= OnCanvasSizeChanged;
this.image = this.GetTemplateChild(ImagePart) as Image;
this.canvas = this.GetTemplateChild(CanvasPart) as Canvas;
if (this.canvas != null)
this.canvas.SizeChanged += OnCanvasSizeChanged;
}
private void OnCanvasSizeChanged(object sender, SizeChangedEventArgs e)
{
if (e.HeightChanged)
this.UpdateVerticalPosition(VerticalPosition);
if (e.WidthChanged)
this.UpadateHorizontalPosition(HorizontalPosition);
}
private void UpadateHorizontalPosition(double position)
{
if (this.image == null || this.canvas == null) return;
double offset = this.CalculateOffset(this.canvas.ActualWidth, this.image.ActualWidth, position);
this.image.SetCurrentValue(Canvas.LeftProperty, offset);
}
private void UpdateVerticalPosition(double position)
{
if (this.image == null || this.canvas == null) return;
double offset = this.CalculateOffset(this.canvas.ActualHeight, this.image.ActualHeight, position);
this.image.SetCurrentValue(Canvas.TopProperty, offset);
}
private double CalculateOffset(double canvasLength, double imageLength, double position)
{
return -(imageLength - canvasLength) * position;
}
}
模板
<Style TargetType="{x:Type local:PositionableImage}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:PositionableImage}">
<Canvas x:Name="PART_Canvas"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Background="{TemplateBinding Background}"
ClipToBounds="True">
<Image x:Name="PART_Image"
Source="{Binding Path=Source, RelativeSource={RelativeSource TemplatedParent}}"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
用法
使用中
你的问题有点不清楚。如果要使用坐标显式定位元素,应该使用画布:定位元素不是问题,实现焦点是问题。焦点?请更具体一些。对不起,我用一个例子编辑了我的问题。也许你在找剪辑属性?解释对象位置是如何工作的已经足够了,但是非常感谢您提供的源代码,它正是我想要的@他们说不客气。我有网络开发的背景,所以和他们结婚很有趣。
<local:PositionableImage Width="60"
Height="60"
Source="H:\test.jpg"
HorizontalPosition=".5"
VerticalPosition=".5"/>