meds
meds

Reputation: 22966

Set width/height to be proportional in xaml?

I'm creating a user control which is of size 300x100, I'd like it to be that resolution on a 1024x768 screen, but on a 2048x1536 screen I'd like it to be 600x200, in general I'd like to set its size proportionally to the height differential (so if the screen is twice as high the control will be twice as high and twice as wide).

Any ideas how I can accomplish this without resorting to code behind (I'm willing to if given no other choice)?

Upvotes: 3

Views: 2890

Answers (2)

peterot
peterot

Reputation: 293

You can solve this without code behind by creating a proxy control. People often use this approach to get correctly updating ActualWidth and ActualHeight properties they can bind to as in the answer to this question.

In your case, you would want to bind the element of the proxy control to some element which is stretching to the full window size. When the width or height of the bound element changes you can then set the value of two properties on your proxy control to be the calculated proportional height and width. You can then just bind to these proportional sizes for the width and height of your user control.

For example:

public class ProportionalSizeHelper : FrameworkElement, INotifyPropertyChanged
{
    private double _proportionalWidth = 0;
    private double _proportionalHeight = 0;

    public event PropertyChangedEventHandler PropertyChanged;

    public FrameworkElement Element
    {
        get { return (FrameworkElement)GetValue(ElementProperty); }
        set { SetValue(ElementProperty, value); }
    }

    public double ProportionalHeight
    {
        get{ return _proportionalHeight; }
    }

    public double ProportionalWidth
    {
        get { return _proportionalWidth; }
    }

    public static readonly DependencyProperty ElementProperty =
        DependencyProperty.Register("Element", typeof(FrameworkElement), typeof(ProportionalSizeHelper), 
                                    new PropertyMetadata(null,OnElementPropertyChanged));

    private static void OnElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((ProportionalSizeHelper)d).OnElementChanged(e);
    }

    private void OnElementChanged(DependencyPropertyChangedEventArgs e)
    {
        FrameworkElement oldElement = (FrameworkElement)e.OldValue;
        FrameworkElement newElement = (FrameworkElement)e.NewValue;

        if (newElement != null)
        {   
            newElement.SizeChanged += new SizeChangedEventHandler(Element_SizeChanged);
        }
        else
        {
            _proportionalHeight = 0;
            _proportionalWidth = 0;
        }
        if (oldElement != null)
        {
            oldElement.SizeChanged -= new SizeChangedEventHandler(Element_SizeChanged);
        }
        NotifyPropChange();
    }

    private void Element_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        // This can be whatever calculation you need
        double factor = Math.Min(Element.ActualWidth/1024, Element.ActualHeight/768);
        _proportionalHeight = 100*factor;
        _proportionalWidth = 300*factor;
        NotifyPropChange();
    }

    private void NotifyPropChange()
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("ProportionalWidth".NonNls()));
            PropertyChanged(this, new PropertyChangedEventArgs("ProportionalHeight".NonNls()));
        }
    }
}

Then in the xaml, with UserControl changed to whatever you need:

<Grid x:Name="LayoutRoot">
    <Grid.Resources>
        <c:ProportionalSizeHelper Element="{Binding ElementName=LayoutRoot}" x:Name="proxy" />
    </Grid.Resources>
    <UserControl Width="{Binding ProportionalWidth, ElementName=proxy}" Height={Binding ProportionalHeight, ElementName=proxy}  />
</Grid>

Upvotes: 2

Anobik
Anobik

Reputation: 4899

This is a silverlight code. Here's how to get the screen height and width

public MainPage()
    {
        InitializeComponent();
        Loaded += new RoutedEventHandler(MainPage_Loaded);
    }
    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        int Width = HtmlPage.Window.Eval("screen.width");
        int Height = HtmlPage.Window.Eval("screen.height");

//Now here increase the height and width of control
double factor = Width/1024; // this is your default you asked for
gdTestElement.Width = 300*factor;
gdTestElement.Height = 100*factor;

        }

:) Try and let me know

Upvotes: 1

Related Questions