我有一个我正在处理的自定义控件,它自己可以正常工作,但是当它是设置宽度的网格时,我会收到如下错误:
元素“Microsoft.Windows.Design.Platform.SilverlightViewProducer+SilverlightContentHost”的布局测量覆盖不应返回 PositiveInfinity 作为其 DesiredSize,即使 Infinity 作为可用大小传入也是如此。
这些错误只发生在我的应用程序中,而不是我的测试工具中 - 但我不能在这里发布前者,但这里可能有一些我遗漏的东西 - 可能能够弥补这个问题 - 但如果有人可以帮助它会很棒
这是类代码:
public class UXImage : Control
{
#region Private Constants
private const string RightImageControl = "RightImage";
private const string MiddleImageControl = "MiddleImage";
private const string LeftImageControl = "LeftImage";
#endregion
#region Private Members
private int sourceHeight;
private int sourceWidth;
private int middleWidth = 1;
WriteableBitmap crop;
TransformGroup transform = new TransformGroup();
TranslateTransform position = new TranslateTransform();
ScaleTransform scale = new ScaleTransform();
// Controls
private Image image = new Image();
private Image rightImageControl;
private Image middleImageControl;
private Image leftImageControl;
#endregion
#region Dependency Properties
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register("Source", typeof(BitmapSource),
typeof(UXImage), null);
public static readonly DependencyProperty RightCapWidthProperty =
DependencyProperty.Register("RightCapWidth", typeof(int),
typeof(UXImage), null);
#endregion
#region Public Properties
public BitmapSource Source
{
get { return (BitmapSource)GetValue(SourceProperty); }
set
{
SetValue(SourceProperty, value);
}
}
public int RightCapWidth
{
get { return (int)GetValue(RightCapWidthProperty); }
set
{
SetValue(RightCapWidthProperty, value);
}
}
#endregion
#region Public Methods
/// <summary>
/// On Apply Template
/// </summary>
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
sourceHeight = Source.PixelHeight;
sourceWidth = Source.PixelWidth;
image.Source = Source;
// Right Element
rightImageControl = (Image)GetTemplateChild(RightImageControl);
crop = new WriteableBitmap(RightCapWidth, sourceHeight);
position.X = -sourceWidth + RightCapWidth;
crop.Render(image, position);
crop.Invalidate();
rightImageControl.Source = crop;
rightImageControl.Width = RightCapWidth;
// Middle Element
middleImageControl = (Image)GetTemplateChild(MiddleImageControl);
crop = new WriteableBitmap(middleWidth, sourceHeight);
position.X = -sourceWidth + RightCapWidth + middleWidth;
crop.Render(image, position);
crop.Invalidate();
middleImageControl.Source = crop;
middleImageControl.Height = sourceHeight;
// Left Element
leftImageControl = (Image)GetTemplateChild(LeftImageControl);
crop = new WriteableBitmap(sourceWidth - RightCapWidth - middleWidth, sourceHeight);
position.X = 0;
crop.Render(image, position);
crop.Invalidate();
leftImageControl.Source = crop;
leftImageControl.Height = sourceHeight;
this.Height = sourceHeight;
this.Width = sourceWidth;
}
public UXImage()
{
DefaultStyleKey = typeof(UXImage);
}
#endregion
}
通用.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
xmlns:local="clr-namespace:UXLibrary">
<Style TargetType="local:UXImage">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:UXImage">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image x:Name="LeftImage" Stretch="Uniform" Source="{TemplateBinding Source}" Grid.Column="0"/>
<Image x:Name="MiddleImage" Stretch="Fill" Grid.Column="1"/>
<Image x:Name="RightImage" Stretch="Uniform" Grid.Column="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</ResourceDictionary>
用法:
<ux:UXImage RightCapWidth="10" Source="Images/example.png"/>
我还没有在 Silverlight 中看到过这样的控件,它基于我听说过但未见过的 iOS 和 Android 9-Patch 中的 UIImage。 谁能帮忙?如果这是一个解决方案,是否有替代方法来做我正在做的事情,作为一个可以在中间拉伸(stretch)的图像元素。
最佳答案
我可以提供有关正在发生的事情的基本概念以及有关如何进行的一些建议。一般而言,Control.Width
和 Control.Height
属性由用户提供,而不是您。 控件 应该将这些值作为输入 并将它们用作布局过程的一部分以影响生成的ActualWidth
和ActualHeight
属性。
现在,即使您从未打算让用户在 XAML 中指定 Width
或 Height
,问题仍然相同。作为控件作者,您应该在 MeasureOverride
和 ArrangeOverride
方法调用期间告诉布局系统您想要的大小,如下所述:
特别是,由于您没有覆盖 MeasureOverride
,默认行为是返回第一个视觉子项的所需大小,在您的情况下将是 Grid
,其大小未指定,因此希望尽可能大,即无限大。
因此,解决方案听起来很简单:在 MeasureOverride
和 ArrangeOverride
而不是 OnApplyTemplate
中计算尺寸,对吧?问题是,您可能无法在正确的时间获得所需的全部信息。如果您不这样做,那么您将需要简单地返回您对所需尺寸的最佳猜测,然后当您获得正确的信息时,强制执行新的布局传递,以便 MeasureOverride
将再次被调用。上面的链接和一般文档描述了如何执行此操作。
关于c# - 具有测量/所需尺寸问题的 Silverlight 控件,图像从中间用户控件拉伸(stretch),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6088200/