Frage

Ich habe eine Anwendung zu erfassen und speichern Bilder in eine Datenbank entwickelt, aber ich habe ein Problem mit der Speichernutzung. Auf meinem Domain-Objekt habe ich 3 Eigenschaften:

Bild - Byte-Array, die Inhalte sind ein jpg

RealImageThumb - Der Byte-Array in eine Bitmap umgewandelt und geschrumpften, angezeigt den Benutzer in einer Gridview mit anderen Thumbnails

RealImage -. Hat keinen Setter, der Byte-Array in einer Bitmap-Quelle umgewandelt, dies wird in einem Tooltip angezeigt, wenn der Benutzer schwebt über ihn

Das Problem, das ich habe, ist, dass, wenn ein Benutzer schwebt über jedes Bild in der Speichernutzung Spiralen drehen. Ich stelle fest, dass sich ein Benutzer schwebt über Bitmap-Quellen erzeugt werden, und der Speicher nicht freigegeben ist, ich habe versucht, RealImage eine Trägereigenschaft zu geben und diese nach zu null zuweisen, aber wieder wird der Speicher für den Müll nicht freigegeben (Warte Sammler?).

edit:

Ist das, was Sie Ray gemeint? Ich bin nicht alles im Tooltip wie unten gezeigt bekommen, aber wenn ich versuche und eine WeakReference<BitmapImage> definieren, ich die System.WeakReference nicht bekommen Typ Parameter Fehler haben.

  private WeakReference _realImage;
        public virtual BitmapImage RealImage
        {
            get
            {
                if (_realImage == null || _realImage.Target == null)
                {

                    if (Image == null) return null;
                    var newBitmapImage = new BitmapImage();
                    newBitmapImage.BeginInit();
                    newBitmapImage.CacheOption = BitmapCacheOption.None;
                    newBitmapImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
                    newBitmapImage.StreamSource = new MemoryStream(Image);
                    newBitmapImage.EndInit();
                    _realImage = new WeakReference(newBitmapImage);
                }

                return (BitmapImage)_realImage.Target;
            }
        }
War es hilfreich?

Lösung

Sie müssen drei Dinge tun:

  1. Wenn Sie Ihre Bitmap Verwendung Stream Konstruktion der Daten zu versorgen. Nicht UriSource verwenden oder ein Uri in den Konstruktor übergeben, die das Bild auf die Bild-Cache hinzugefügt werden.

  2. verursachen würden
  3. In Ihrer Domäne RealImage Implementierung des Objekts, speichern Sie eine WeakReference auf Ihre Bitmap nicht die Bitmap selbst. Wenn RealImage geholt wird, wenn entweder WeakReference oder WeakReference.Target null ist, erstellen Sie eine neue Bitmap und ein neues WeakReference zu.

  4. Mit einem Datatrigger mit Vorlage Umschaltung auf nur Ihre Bildsteuerung in der visuellen Struktur enthält, wenn es sichtbar ist

Hier sind die benötigten Vorlagen für Schritt 3, einschließlich dem mit den Datatrigger:

<DataTemplate x:Key="EmptyTemplate">
</DataTemplate>

<DataTemplate x:Key="RealImageTemplate">
  <Image Source="{Binding RealImage.Target}" Width="300" Height="300" />
</DataTemplate>

<DataTemplate x:Key="RealImageWhenVisible">

  <!-- Use EmptyTemplate when I am not visible -->
  <ContentPresenter x:Name="Presenter"
                    Content="{Binding}"
                    ContentTemplate="{StaticResource EmptyTemplate}"/>

  <!-- Switch to RealImageTemplate when I am visible -->
  <DataTemplate.Triggers>
    <DataTrigger Binding="{Binding IsVisible, RelativeSource={RelativeSource Self}}"
                 Value="True">
      <Setter TargetName="Presenter"
              Property="ContentPresenter.ContentTemplate"
              Value="{StaticResource RealImageTemplate}" />
    </DataTrigger>
  </DataTemplate.Triggers>
</DataTemplate>

Jetzt können Sie Ihre Quick-Info wie folgt definieren:

<Rectangle Width="40" Height="40" Fill="Blue">
  <Rectangle.ToolTip>
    <ContentPresenter Content="{Binding}"
                      ContentTemplate="{StaticResource RealImageWhenVisible}" />
  </Rectangle.ToolTip>
</Rectangle>

Wie es funktioniert: Es gibt zwei ContentPresenters ineinander:

  • Wenn die äußere Content unsichtbar ist, die innere Content wird EmptyTemplate haben, so wird kein Bild geladen werden.
  • Wenn die äußere Content sichtbar ist, die innere Content wird RealImageTemplate haben so das Bild geladen und angezeigt.

Der Grund, warum Sie müssen dies tun, ist, dass eine Quick-Info zu optimieren Leistung kann versuchen, indem nicht den Popup Entsorgung einmal gezeigt wurde.

Aktualisieren

Der Code, den Sie für RealImage geschrieben sollten Arbeit und ist fast genau das, was ich gedacht hatte. Ich erkannte, heute Morgen gibt es wirklich keine Notwendigkeit BitmapCacheOption oder BitmapCreateOption so lange einzustellen, wie kein SourceUri angegeben ist. Ich habe meine Antwort aktualisiert diese zu reflektieren und auch die WeakReference Sache zu klären. Ich korrigierte auch einen Fehler in der Vorlage: I „RealImage“ wurde verbindlich, wenn ich auf „RealImage.Target“ wurde Bindung sollte

.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top