Freek W.
Freek W.

Reputation: 406

How do I bind dynamic byte array to button background in WPF

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.

Upvotes: 0

Views: 364

Answers (2)

Clemens
Clemens

Reputation: 128077

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();
}

Upvotes: 1

Travis Acton
Travis Acton

Reputation: 4440

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;

Upvotes: 0

Related Questions