UserControl to display 16x16 or 32x32 images - wpf

I have a control that assembles a final image from multiple PNG files. The individual png files are chosen based on item states bound to the control. i.e. overlayed - but that all works fine.
Each image file is created in two sizes 16x16 and 32x32 (i.e. like an icon)
From the VS designer (or code) I want the user to be able to specify whether they want the 16x16 or 32x32 version. So I added a dependency property ImgSize. I've made it an int so I can set it to 16 or 32. So a user of this control simply XAMLs
<xyz:thisControl ImgSize="32"/>
and the DataContext supplies all the binding particulars.
I want the width and height of the user control to be automatically set to the corresponding image size. So binding like so makes sense:
<UserControl x:Class="...
Width="{Binding Path=ImgSize}"
Height="{Binding Path=ImgSize}"
When that didn't work, I tried every RelativeSource binding I could - no luck. Is there an additional layer of plumbing/binding/events I'm missing?
Thanks,
Dan

Why don't you just use the built-in width and height of the UserControl?
These properties are bindable by default

Related

Get padding caused by stretch value Uniform

A WPF UI element has defined a width and height, the background is set to an image brush and pointed the image source to some random images on run-time. The stretch property is not set, hence I assume it is the default value "Fill" that comes into play. Since control size and image size are different, in run-time, the background image brush is filled with some aspect ratio, i.e with a padding (visually) inside the control. Is there a way to get this padded values?
Sample code :
<Grid Width="2000" Height="2000">
<ListBox>
<ListBox.Background>
<ImageBrush ImageSource="{Binding Source={x:Static local:MyModel.Instance},Path=ImageSource,Converter={StaticResource pathImageConverter}}" />
</ListBox.Background>
</ListBox>
</Grid>
Instead of image brush if I use a color, it fills the entire area.But if I use an image say 5000 * 4000 dimension, it stretches somewhat to fill inside the space (without skewing and cropping). That is not the real padding, visually we feel there is a padding from the list box boundaries and image boundaries. Let me try to get a snapshot of this.
There are multiple tools to get those values, and where they are assigned when running the application:
XAMLSpy
Snoop
And probably more, but these are the ones I use when encountering a problem like yours.
There is no API to get those values, I'm afraid you need to do the calculations yourself. Let me elaborate...
As indicated in the comments, the ImageBrush is not causing your padding. The brush will simply paint the area it gets. Of course, depending on the mode of the ImageBrush, it won't paint the entire area, but only a portion. Changing the brush to a SolidColorBrush will show you the entire area the brush will get. That should be identical to the area the image brush will fill, if it's put in... well, Fill mode.
However, I highly doubt it's the brush, but rather the ControlTemplate of the ListBox. If you're running in the Aero theme, by default, the template starts with a Border, which has its Background property template binded back to the ListBox, and it does the same with the BorderThickness (and to make things worse, it also has a fixed padding of 1, however, the background is drawn on top of that).
So to calculate the "padding" of the brush, you need to do the same as Border does: BorderThickness + Padding.
However, if you're running in a different theme, or if your controls have been restyled, then your control templates might be different, and the calculation might be different...

ViewBox automatically change postion of my control

I am writing an application using WPF in visual studio 2012.
I want to use Viewbox control to solve problem of resizing application. Now when I try to place other controls in Viewbox, I see that I can't change the position of controls. It seems that Viewbox change automatically the positions of controls!
Picture(1) is result
and picture(2) is what I want.
picture(1)
picture(2)
Please help me.
You need to specify how you want the ViewBox to align the child element it's stretching.
<Viewbox VerticalAlignment="Top">
Should place your elements at your desired location.
You can also specify how the ViewBox will Stretch it's content, and the HorizontalAlignment, if required.
Additionaly, you can specify StretchDirection="UpOnly", to ensure that your controls are never scaled below the initial size you specify.

Fill the non-standard shape WPF window with an image

I have created a non standard shaped window with the
WindowStyle="None"
AllowsTransparency="True"
Background="Transparent"
approach.
I have arrived at the following:
A windows has a grid. The grid has an Image control (a superman logo) and a border control (blue panel) that will in turn contain listbox that is not yet visible due to the absense of elements.
At some point I need to fill an entire window with a patter, so I woul arrive at something like this:
If I just fill separate controls with a pattern, it wouldn't appear to be smoothly distributed along the page.
So my idea is to somehow dynamically get the path element out of the window and fill it with a pattern I need, and then display.
Can this be done via code at runtime?
A Path is probably the easiest way I know of, and is what I usually do for non-standard window shapes

Sizing WPF windows automatically

When designing WPF dialog windows in the XAML designer (that are not manually resizeable by the user), the windows automatically resize to fit their content, and everything is fine. But when I run my app, the windows become huge and there's a lot of empty space.
I know this is a "feature" of WPF that can be "fixed" by setting the SizeToContent tag, but another issue arises when I do this: If the window contains a textbox, for instance, and the user enters data that overflows the visible area, the window will stretch to accommodate it. This happens with listboxes, treeviews, you name it.
All I want is for Visual Studio to figure out the ideal window size that it shows me at design time, then set the window to be that size at runtime, and don't change the size after that. It seems like this should be an easy thing to do.
Edit: Figured out part of the problem: I have controls set up in a grid, and the column's width is set to "Auto" which is why everything is resizing.
Use View Box
The ViewBox is a very useful control in WPF. If does nothing more than scale to fit the content to the available size. It does not resize the content, but it transforms it. This means that also all text sizes and line widths were scaled. Its about the same behavior as if you set the Stretch property on an Image or Path to Uniform.
Although it can be used to fit any type of control, it's often used for 2D graphics, or to fit a scalable part of a user interface into an screen area.
<Viewbox>
<Enter your code/>
</Viewbox>
Try setting the window's height and width to Auto. Also, remove the SizeToContent attribute. This should fix it.
I do not think that this is this is something which is commonly requested so it's probably not easy to do, one method i can think of would be starting with automatic SizeToContent and handling the Loaded event and setting:
Height = ActualHeight;
Width = ActualWidth;
SizeToContent = System.Windows.SizeToContent.Manual;

How to resize multiple WPF controls when the text size changes?

What's the correct pattern to resize controls when a font size changes?
For example, I used the WPF designer to make a form, and placed UI elements from the toolbox. Late in the game I got the requirement that the font size of every UI element needs to be configurable, so now I'm thinking there has to be a better way to resize controls when the font size changes. Right now I'm doing alot of code behind calculations on Margin properties.
For such cases I usually place my control inside Grids and StackPanels, this way font size won't affect the layout, everything will be stretchable.
Never place controls on the Window using absolute coordinates.
Make sure your Height and Width on the controls are set to Auto.
When you use the designer/toolbox to add controls it usually provides a static height/width. If you type the tag in the XAML editor you get the control default which is usually Auto.
You'll notice the black diamond in the property window next to the attributes that are changed from their default value. You can right click and choose reset value to clear the attribute from your XAML and see what the default value is.

Resources