ListView Virtualization导致Control出错状态

时间:2015-10-21 12:33:37

标签: c# windows win-universal-app uwp

我创建了一个简单的控件来预览缩略图图像并显示完整图像(如果已下载)。此控件嵌套在ListView中。但是,如果滚动ListView,则项目将被回收,但我的控件将无法保持正确状态。即使图像已下载且仍无法点击,它也会显示预览。有人可以解释一下我做错了什么吗?所有数据都绑定到控件。

[TemplateVisualState(Name = "Preview", GroupName = "ControlStates")]
[TemplateVisualState(Name = "Fullview", GroupName = "ControlStates")]
public class Attachment : Control
{

    public ImageSource Image
    {
        get { return (ImageSource)GetValue(ImageProperty); }
        set { SetValue(ImageProperty, value); }
    }
    public static DependencyProperty ImageProperty = DependencyProperty.Register("Image", typeof(ImageSource), typeof(Attachment), new PropertyMetadata(null, new PropertyChangedCallback((A, B) => ((Attachment)A).OnImageChanged())));
    private void OnImageChanged()
    {
        if (Image == null)
            VisualStateManager.GoToState(this, "Preview", true);
        else
            VisualStateManager.GoToState(this, "Fullview", true);
    }

    public ImageSource Thumbnail
    {
        get { return (ImageSource)GetValue(ThumbnailProperty); }
        set { SetValue(ThumbnailProperty, value); }
    }
    public static DependencyProperty ThumbnailProperty = DependencyProperty.Register("Thumbnail", typeof(ImageSource), typeof(Attachment), new PropertyMetadata(null, new PropertyChangedCallback((A, B) => ((Attachment)A).OnThumbnailChanged())));
    private void OnThumbnailChanged()
    {
        if (Image == null)
            VisualStateManager.GoToState(this, "Preview", true);
        else
            VisualStateManager.GoToState(this, "Fullview", true);
    }


    public bool IsAttachmentDownloading
    {
        get { return (bool)GetValue(IsAttachmentDownloadingProperty); }
        set { SetValue(IsAttachmentDownloadingProperty, value); }
    }
    public static readonly DependencyProperty IsAttachmentDownloadingProperty =
        DependencyProperty.Register("IsAttachmentDownloading", typeof(bool), typeof(Attachment), new PropertyMetadata(false));

    public ICommand DownloadAttachment
    {
        get { return (ICommand)GetValue(DownloadAttachmentProperty); }
        set { SetValue(DownloadAttachmentProperty, value); }
    }
    public static readonly DependencyProperty DownloadAttachmentProperty =
        DependencyProperty.Register("DownloadAttachment", typeof(ICommand), typeof(Attachment), new PropertyMetadata(null));

    public object DownloadAttachmentParameter
    {
        get { return (object)GetValue(DownloadAttachmentParameterProperty); }
        set { SetValue(DownloadAttachmentParameterProperty, value); }
    }
    public static readonly DependencyProperty DownloadAttachmentParameterProperty =
        DependencyProperty.Register("DownloadAttachmentParameter", typeof(object), typeof(Attachment), new PropertyMetadata(null));

    public object DownloadAttachmentContent
    {
        get { return (object)GetValue(DownloadAttachmentContentProperty); }
        set { SetValue(DownloadAttachmentContentProperty, value); }
    }
    public static readonly DependencyProperty DownloadAttachmentContentProperty =
        DependencyProperty.Register("DownloadAttachmentContent", typeof(object), typeof(Attachment), new PropertyMetadata(null));


    Button _DownloadAttachmentButton = null;

    public Attachment()
    {
        this.DefaultStyleKey = typeof(Attachment);
        this.Loaded += Attachment_Loaded;
    }

    private void Attachment_Loaded(object sender, RoutedEventArgs e)
    {
        if (Image == null)
            VisualStateManager.GoToState(this, "Preview", true);
        else
            VisualStateManager.GoToState(this, "Fullview", true);
    }

    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        //this._DownloadAttachmentButton = GetTemplateChild("PART_DownloadAttachmentButton") as Button;
    }
}


<Style TargetType="local:Attachment">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:Attachment">
                <Border x:Name="PART_Border" Opacity="1">
                    <Grid>
                        <Rectangle Fill="{TemplateBinding Background}"/>
                        <Grid x:Name="PART_ThumbContainer" Opacity="1">
                            <Rectangle Fill="{TemplateBinding Background}"/>
                            <Image x:Name="PART_Thumb" Stretch="UniformToFill" Source="{TemplateBinding Thumbnail}"/>
                            <Button Command="{TemplateBinding DownloadAttachment}" BorderThickness="0" Background="#AA000000"
                                    CommandParameter="{TemplateBinding DownloadAttachmentParameter}" 
                                    VerticalAlignment="Center" HorizontalAlignment="Center">
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="&#xE118;" FontFamily="Segoe MDL2 Assets" Margin="0,0,5,0"
                                               Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}" 
                                               FontWeight="{TemplateBinding FontWeight}" FontStyle="{TemplateBinding FontStyle}"/>
                                    <TextBlock Text="{TemplateBinding DownloadAttachmentContent}"
                                               Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}" 
                                               FontWeight="{TemplateBinding FontWeight}" FontFamily="{TemplateBinding FontFamily}" 
                                               FontStyle="{TemplateBinding FontStyle}"/>
                                </StackPanel>
                            </Button>
                        </Grid>
                        <Grid x:Name="PART_ImageContainer" Opacity="0">
                            <Rectangle Fill="{TemplateBinding Background}"/>
                            <Image x:Name="PART_Image" Stretch="UniformToFill" Source="{TemplateBinding Image}" />
                        </Grid>
                    </Grid>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="ControlStates">
                            <VisualState x:Name="Preview">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_ThumbContainer" Storyboard.TargetProperty="Opacity">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="1"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_ImageContainer" Storyboard.TargetProperty="Opacity">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="0"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Fullview">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_ThumbContainer" Storyboard.TargetProperty="Opacity">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="0"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_ImageContainer" Storyboard.TargetProperty="Opacity">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="1"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

1 个答案:

答案 0 :(得分:0)

我想,您应该在OnApplyTemplate中调用负责状态更改的代码。我的意思是:

protected override void OnApplyTemplate()
{
    base.OnApplyTemplate();

     if (Image == null)
        VisualStateManager.GoToState(this, "Preview", true);
    else
        VisualStateManager.GoToState(this, "Fullview", true);
}

可能在控制权被回收再次显示后,OnApplyTemplate启动。检查一下。