我编写了一个自定义控件,旨在在加载实际图像时显示占位符图像。它是用通用应用程序编写的。 这是我控制的代码:
public class DeferredImage : Control
{
public static readonly DependencyProperty PlaceholderSourceProperty =
DependencyProperty.Register("PlaceholderSource", typeof(ImageSource), typeof(DeferredImage), new PropertyMetadata(null, OnPlaceholderSourcePropertyChanged));
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register("Source", typeof(ImageSource), typeof(DeferredImage), new PropertyMetadata(null, OnSourcePropertyChanged));
public static readonly DependencyProperty StretchProperty =
DependencyProperty.Register("Stretch", typeof(Stretch), typeof(DeferredImage), new PropertyMetadata(Stretch.Uniform, OnStretchPropertyChanged));
private const string PlaceholderImageName = "PlaceholderImage";
private const string ActualImageName = "ActualImage";
private const string DefaultStateName = "DefaultState";
private const string ActualStateName = "ActualState";
private Image _placeholderImage;
private Image _actualImage;
public ImageSource PlaceholderSource
{
get { return (ImageSource)GetValue(PlaceholderSourceProperty); }
set { SetValue(PlaceholderSourceProperty, value); }
}
public ImageSource Source
{
get { return (ImageSource)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
public Stretch Stretch
{
get { return (Stretch)GetValue(StretchProperty); }
set { SetValue(StretchProperty, value); }
}
public DeferredImage()
{
DefaultStyleKey = typeof(DeferredImage);
}
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
_placeholderImage = GetTemplateChild(PlaceholderImageName) as Image;
_actualImage = GetTemplateChild(ActualImageName) as Image;
if (_placeholderImage != null)
{
_placeholderImage.Source = PlaceholderSource;
_placeholderImage.Stretch = Stretch;
}
if (_actualImage != null)
{
_actualImage.Source = Source;
_actualImage.Stretch = Stretch;
}
}
private static void OnPlaceholderSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var defferedImage = d as DeferredImage;
if (defferedImage != null && defferedImage._placeholderImage != null)
{
defferedImage._placeholderImage.Source = (ImageSource)e.NewValue;
}
}
private static void OnSourcePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var defferedImage = o as DeferredImage;
if (defferedImage != null && defferedImage._actualImage != null)
{
var newImageSource = (ImageSource)e.NewValue;
defferedImage._actualImage.Source = newImageSource;
VisualStateManager.GoToState(defferedImage, newImageSource == null ? DefaultStateName : ActualStateName, false);
}
}
private static void OnStretchPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var instance = d as DeferredImage;
if (instance != null)
{
if (instance._placeholderImage != null)
instance._placeholderImage.Stretch = (Stretch)e.NewValue;
if (instance._actualImage != null)
instance._actualImage.Stretch = (Stretch)e.NewValue;
}
}
}
以下是控件模板的代码:
<Style TargetType="controls:DeferredImage">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:DeferredImage">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="DefaultState">
<Storyboard>
<DoubleAnimation Duration="0:0:0.3"
To="1"
Storyboard.TargetName="PlaceholderImage"
Storyboard.TargetProperty="Opacity" />
<DoubleAnimation Duration="0:0:0.3"
To="0"
Storyboard.TargetName="ActualImage"
Storyboard.TargetProperty="Opacity" />
</Storyboard>
</VisualState>
<VisualState x:Name="ActualState">
<Storyboard>
<DoubleAnimation Duration="0:0:0.3"
To="0"
Storyboard.TargetName="PlaceholderImage"
Storyboard.TargetProperty="Opacity" />
<DoubleAnimation Duration="0:0:0.3"
To="1"
Storyboard.TargetName="ActualImage"
Storyboard.TargetProperty="Opacity" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Image Name="PlaceholderImage"
Opacity="1"
Canvas.ZIndex="-1" />
<Image Name="ActualImage"
Opacity="0" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
乍一看,这似乎运作正常。但我遇到了问题:当我旋转平板电脑时,我在OnApplyTemplate方法之后调用了OnSourcePropertyChanged处理程序。因此,_actualImage字段在OnSourcePropertyChanged处理程序中等于NULL,并且在旋转平板电脑后我没有显示我的图像。
有人知道旋转后Control的工作流程吗?问题出在哪里?
答案 0 :(得分:0)
通过添加
解决了这个问题 OnApplyTemplate方法中的 VisualStateManager.GoToState(defferedImage, newImageSource == null ? DefaultStateName : ActualStateName, false);
。