0

I'm trying to create a custom control that has a specific set of values on it. Also it has some custom events. I've been trying to get my byte array (blob) that I get from the database into my Custom Control background (button).

<Button  Width="{Binding x}" Height="{Binding y}" VerticalAlignment="Center" Padding="100" Margin="1" FontSize="100" >
    <Image Source="{Binding image_link}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Height="{Binding x}" Width="{Binding y}" />
</Button>

And my custom control:

[JsonProperty("consoleButton.id")]
    public int id { get; set; }

    [JsonProperty("consoleButton.parent_id")]
    public int? parent_id { get; set; }

    [JsonProperty("consoleButton.console_id")]
    public int console_id { get; set; }

    [JsonProperty("consoleButton.image_link")]
    public byte[] image_link { get; set; }

    public string website_link { get; set; }

    [JsonProperty("consoleButton.tag_name")]
    public string tag_name { get; set; }

    [JsonProperty("consoleButton.button_type")]
    public Miscellaneous.Enums.buttontype button_type { get; set; }

    public int x { get; set; }
    public int y { get; set; }
    //public string name { get; set; }

    public BitmapImage brush { get; set; }


    public ImageButton(int id, int? parent_id, int console_id, byte[] image_link, string website_link, string tag_name, Miscellaneous.Enums.buttontype button_type, int x, int y, double convertSize)
    {

        InitializeComponent();
        this.id = id;
        //this.name = "btn" + id.ToString();
        this.parent_id = parent_id;
        this.console_id = console_id;
        this.image_link = image_link;
        this.website_link = website_link;
        this.tag_name = tag_name;
        this.button_type = button_type;
        this.x = Convert.ToInt32(x * convertSize);
        this.y = Convert.ToInt32(y * convertSize);

        BitmapImage btm;
        using (MemoryStream ms = new MemoryStream(image_link))
        {
            btm = new BitmapImage();
            btm.BeginInit();
            btm.StreamSource = ms;
            // Below code for caching is crucial.
            btm.CacheOption = BitmapCacheOption.OnLoad;
            btm.EndInit();
            btm.Freeze();
        }
        brush = btm;
    }

I've tried a few thing as you can see (added extra code) but nothing seems to work.

1
  • Are the x and y Bindings working? Commented Aug 24, 2017 at 6:44

2 Answers 2

1

When you bind a UserControl's UI elements to own properties of the UserControl, you'll have to set the control instance as source object of the Binding.

One way to do that is to set the RelativeSource property:

<Image Source="{Binding image_link,
                RelativeSource={RelativeSource AncestorType=UserControl}}" .../>

Note that you do not need an extra ImageSource (or BitmapImage) property like your brush property. WPF provides built-in type conversion, which will automatically convert byte[] to ImageSource.


Since your control's properties do not fire a change notification, it may also be necessary to set their value before calling InitializeComponent:

public ImageButton(...)
{
    ...
    this.image_link = image_link;
    ...
    InitializeComponent();
}
Sign up to request clarification or add additional context in comments.

2 Comments

Changed code to <Button Width="{Binding x}" Height="{Binding y}" VerticalAlignment="Center" Padding="120" Margin="5" FontSize="100" > <Image Source="{Binding image_link, RelativeSource={RelativeSource AncestorType=UserControl}}" Height="270" Width="240" VerticalAlignment="Top" HorizontalAlignment="Left"/> </Button> and put the InitializeComponent(); on the bottom of the constructor but nothing appeared yet.
On second note it seems to work! (Somehow the picture is hidden when the button is smaller?) But since your code works I will mark it as answered! Thanks for the help.
0

You are binding to the wrong property from what i can tell: Source="{binding image_link} when I believe it should be Source="{binding brush}

(Tiny restructuring of code btw):

    BitmapImage btm = new BitmapImage();
    using (MemoryStream ms = new MemoryStream(image_link))
    {
        ms.Position = 0;
        btm.BeginInit();
        btm.StreamSource = ms;
        btm.CacheOption = BitmapCacheOption.OnLoad;
        btm.EndInit();
    }
    btm.Freeze();
    brush = btm;

5 Comments

I added brush as binding Image Source="{Binding brush}" like so, but i get no different result (just a grey button).
have you verified your BitmapImage is actually valid and being created?
Well the byte array is a valid byte array, because i built the entire application before but in WinForms and there I used (Bitmap)((new ImageConverter()).ConvertFrom(image_link)); within the memory stream.
The "restructuring of code" makes no sense. Where is the functional difference to the original code? Setting ms.Position = 0 is redundant, because the MemoryStream was just created.
For {Binding image_link} vs {Binding brush}, the former should also just work, because built-in type conversion does actually convert from byte[] to ImageSource. Hence the whole brush property and the BimatImage craetion code is redundant.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.