Last active
April 8, 2019 09:23
-
-
Save darinkes/e513c861e47375c0070e7ec38857e2f3 to your computer and use it in GitHub Desktop.
AvaloniaUI Image with Updateable Source
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Avalonia; | |
using Avalonia.Controls; | |
using Avalonia.Media; | |
using Avalonia.Media.Imaging; | |
using Avalonia.Platform; | |
using System; | |
namespace Test.Desktop | |
{ | |
public class MyImage : Control | |
{ | |
/// <summary> | |
/// Defines the <see cref="Source"/> property. | |
/// </summary> | |
public static readonly StyledProperty<string> SourceProperty = | |
AvaloniaProperty.Register<Image, string>(nameof(Source)); | |
/// <summary> | |
/// Defines the <see cref="Stretch"/> property. | |
/// </summary> | |
public static readonly StyledProperty<Stretch> StretchProperty = | |
AvaloniaProperty.Register<Image, Stretch>(nameof(Stretch), Stretch.Uniform); | |
static MyImage() | |
{ | |
AffectsRender<Image>(SourceProperty, StretchProperty); | |
AffectsMeasure<Image>(SourceProperty, StretchProperty); | |
} | |
private IBitmap bitmap; | |
public string Source | |
{ | |
get { return GetValue(SourceProperty); } | |
set | |
{ | |
SetValue(SourceProperty, value); | |
if (!string.IsNullOrEmpty(value)) | |
{ | |
var uri = value.StartsWith("/") | |
? new Uri(value, UriKind.Relative) | |
: new Uri(value, UriKind.RelativeOrAbsolute); | |
var assets = AvaloniaLocator.Current.GetService<IAssetLoader>(); | |
bitmap = new Bitmap(assets.Open(uri)); | |
} | |
else | |
{ | |
bitmap = null; | |
} | |
} | |
} | |
/// <summary> | |
/// Gets or sets a value controlling how the image will be stretched. | |
/// </summary> | |
public Stretch Stretch | |
{ | |
get { return (Stretch)GetValue(StretchProperty); } | |
set { SetValue(StretchProperty, value); } | |
} | |
/// <summary> | |
/// Renders the control. | |
/// </summary> | |
/// <param name="context">The drawing context.</param> | |
public override void Render(DrawingContext context) | |
{ | |
var source = bitmap; | |
if (source != null) | |
{ | |
Rect viewPort = new Rect(Bounds.Size); | |
Size sourceSize = new Size(source.PixelSize.Width, source.PixelSize.Height); | |
Vector scale = Stretch.CalculateScaling(Bounds.Size, sourceSize); | |
Size scaledSize = sourceSize * scale; | |
Rect destRect = viewPort | |
.CenterRect(new Rect(scaledSize)) | |
.Intersect(viewPort); | |
Rect sourceRect = new Rect(sourceSize) | |
.CenterRect(new Rect(destRect.Size / scale)); | |
var interpolationMode = RenderOptions.GetBitmapInterpolationMode(this); | |
context.DrawImage(source, 1, sourceRect, destRect, interpolationMode); | |
} | |
} | |
/// <summary> | |
/// Measures the control. | |
/// </summary> | |
/// <param name="availableSize">The available size.</param> | |
/// <returns>The desired size of the control.</returns> | |
protected override Size MeasureOverride(Size availableSize) | |
{ | |
var source = bitmap; | |
if (source != null) | |
{ | |
Size sourceSize = new Size(source.PixelSize.Width, source.PixelSize.Height); | |
if (double.IsInfinity(availableSize.Width) || double.IsInfinity(availableSize.Height)) | |
{ | |
return sourceSize; | |
} | |
else | |
{ | |
return Stretch.CalculateSize(availableSize, sourceSize); | |
} | |
} | |
else | |
{ | |
return new Size(); | |
} | |
} | |
/// <inheritdoc/> | |
protected override Size ArrangeOverride(Size finalSize) | |
{ | |
var source = bitmap; | |
if (source != null) | |
{ | |
var sourceSize = new Size(source.PixelSize.Width, source.PixelSize.Height); | |
var result = Stretch.CalculateSize(finalSize, sourceSize); | |
return result; | |
} | |
else | |
{ | |
return new Size(); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<local:MyImage Source="resm:default.png" VerticalAlignment="Center" Margin="5" Width="24" Height="24"> | |
<i:Interaction.Behaviors> | |
<ia:DataTriggerBehavior Binding="{Binding State}" ComparisonCondition="Equal" Value="STATE1"> | |
<ia:ChangePropertyAction PropertyName="Source" Value="resm:state1.png"/> | |
</ia:DataTriggerBehavior> | |
<ia:DataTriggerBehavior Binding="{Binding State}" ComparisonCondition="Equal" Value="STATE2"> | |
<ia:ChangePropertyAction PropertyName="Source" Value="resm:state2.png"/> | |
</ia:DataTriggerBehavior> | |
<ia:DataTriggerBehavior Binding="{Binding State}" ComparisonCondition="Equal" Value="STATE3"> | |
<ia:ChangePropertyAction PropertyName="Source" Value="resm:state3.png"/> | |
</ia:DataTriggerBehavior> | |
</i:Interaction.Behaviors> | |
</local:MyImage> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment