locked
Adjusting binding values RRS feed

  • Question

  • Hello guys,

    I have the following code which works just fine:

    <Grid Name="SpiderGrid"
      Width="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Width}"
      Height="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Height}">
    </Grid>


    But what I want now is this:
    Width = WorkArea width - 70
    Height = WorkArea height - 110

    Could you please help me rewrite the above code in a way WPF engine can understand please?

    Thank you :)
    • Edited by LoveRiysa Tuesday, May 19, 2009 3:26 AM
    Tuesday, May 19, 2009 3:21 AM

Answers

  • hi,

    You can also try a simple workaround by converting the width and height to a resource.....

    In App.xaml.cs you can try

    public App()
    
            {
    
                this.Resources["GridWidth"] = SystemParameters.WorkArea.Width - 370;
    
                this.Resources["GridHeight"] = SystemParameters.WorkArea.Width - 570;
    
            }

     

    and in window1.xaml you can write ....

    <Window x:Class="forims.Window1"
    
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    
        Title="Window1" WindowState="Maximized">
    
        <Grid Width="{DynamicResource GridWidth}" Height="{DynamicResource GridHeight}" Background="Red">
    
            
    
        </Grid>
    
    </Window>

    Hope it helps.


    Developer : Please mark the post as helpful or Answered if founded
    • Edited by Tarun Jindal Tuesday, May 19, 2009 8:16 AM
    • Proposed as answer by Tarun Jindal Tuesday, May 19, 2009 8:16 AM
    • Proposed as answer by Tao Liang Tuesday, May 19, 2009 8:17 AM
    • Marked as answer by LoveRiysa Tuesday, May 19, 2009 4:11 PM
    Tuesday, May 19, 2009 8:15 AM

All replies

  • You could use Converter in the Binding.
    In the code of Converter, you can do some arithmetic operations such as
     Width = WorkArea width - 70

    One method is to inherit from IValueConverter.
    Or you could use Microsoft.JScript to do more complex calculation.

    Below is a simple demo project that show this two method.

    First add reference to Microsoft.JScript and then run the program.
    For example:
    XAML
    <Window x:Class="WindowsApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WindowsApplication1"
        Title="WindowsApplication1" Height="1000" Width="300"
        >
    	<StackPanel>
    		<StackPanel.Resources>
    			<local:JScriptConverter x:Key="JScript" TrapExceptions="False"/>
    			<local:ArithmeticConverter x:Key="AScript"/>
    		</StackPanel.Resources>
    		<TextBox Name="tb1" Height="200"/>
    		<TextBlock Height="{Binding ElementName=tb1, Path=ActualHeight,
        Converter={StaticResource JScript}, 
        ConverterParameter=Int32.Parse(values[0])/10 *50-500 }" Background="Red"/>
    		<TextBlock Height="{Binding ElementName=tb1, Path=ActualHeight,
        Converter={StaticResource AScript}, 
        ConverterParameter=Int32.Parse(values[0])-100 }" Background="Yellow"/>
    	</StackPanel>
    </Window>
    

    C#
    using System;
    using System.Windows.Data;
    using System.CodeDom.Compiler;
    using System.Text.RegularExpressions;
    using System.Reflection;
    namespace WindowsApplication1
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : System.Windows.Window
        {
            public Window1()
            {
                InitializeComponent();
            }
        }
        class ArithmeticConverter : IValueConverter
        {
            private const string ArithmeticParseExpression = "([+\\-*/]{1,1})\\s{0,}(\\-?[\\d\\.]+)";
            private Regex arithmeticRegex = new Regex(ArithmeticParseExpression);
            #region IValueConverter Members
            object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                if (value is double && parameter != null)
                {
                    string param = parameter.ToString();
                    if (param.Length > 0)
                    {
                        Match match = arithmeticRegex.Match(param);
                        if (match != null && match.Groups.Count == 3)
                        {
                            string operation = match.Groups[1].Value.Trim();
                            string numericValue = match.Groups[2].Value;
                            double number = 0;
                            if (double.TryParse(numericValue, out number)) // this should always succeed or our regex is broken
                            {
                                double valueAsDouble = (double)value;
                                double returnValue = 0;
                                switch (operation)
                                {
                                    case "+":
                                        returnValue = valueAsDouble + number;
                                        break;
                                    case "-":
                                        returnValue = valueAsDouble - number;
                                        break;
                                    case "*":
                                        returnValue = valueAsDouble * number;
                                        break;
                                    case "/":
                                        returnValue = valueAsDouble / number;
                                        break;
                                }
                                return returnValue;
                            }
                        }
                    }
                }
                return null;
            }
            object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new Exception("The method or operation is not implemented.");
            }
            #endregion
        }
        public class JScriptConverter : IMultiValueConverter, IValueConverter
        {
            private delegate object Evaluator(string code, object[] values);
            private static Evaluator evaluator;
            static JScriptConverter()
            {
                string source =
                    @"import System; 
                    class Eval
                    {
                        public function Evaluate(code : String, values : Object[]) : Object
                        {
                            return eval(code);
                        }
                    }";
                CompilerParameters cp = new CompilerParameters();
                cp.GenerateInMemory = true;
                foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
                    if (System.IO.File.Exists(assembly.Location))
                        cp.ReferencedAssemblies.Add(assembly.Location);
                CompilerResults results = (new Microsoft.JScript.JScriptCodeProvider())
                    .CompileAssemblyFromSource(cp, source);
                Assembly result = results.CompiledAssembly;
                Type eval = result.GetType("Eval");
                evaluator = (Delegate.CreateDelegate(
                    typeof(Evaluator),
                    Activator.CreateInstance(eval),
                    "Evaluate") as Evaluator);
            }
            private bool trap = false;
            public bool TrapExceptions
            {
                get { return this.trap; }
                set { this.trap = true; }
            }
            public object Convert(object[] values, System.Type targetType,
                object parameter, System.Globalization.CultureInfo culture)
            {
                try
                {
                    return evaluator(parameter.ToString(), values);
                }
                catch
                {
                    if (trap)
                        return null;
                    else
                        throw;
                }
            }
            public object Convert(object value, Type targetType,
                object parameter, System.Globalization.CultureInfo culture)
            {
                return Convert(new object[] { value }, targetType, parameter, culture);
            }
            public object[] ConvertBack(object value, System.Type[] targetTypes,
                object parameter, System.Globalization.CultureInfo culture)
            {
                throw new System.NotSupportedException();
            }
            public object ConvertBack(object value, Type targetType,
                object parameter, System.Globalization.CultureInfo culture)
            {
                throw new System.NotSupportedException();
            }
        }
    }
    • Edited by Tao Liang Tuesday, May 19, 2009 3:35 AM
    • Proposed as answer by Tao Liang Tuesday, May 19, 2009 3:35 AM
    Tuesday, May 19, 2009 3:24 AM
  • You could use Converter in the Binding.

    I am very new to XAML. Could you please show me some samples?

    Thank you :)
    Tuesday, May 19, 2009 3:27 AM
  • You could use Converter in the Binding.

    I am very new to XAML. Could you please show me some samples?

    Thank you :)
    I paste some code above.
    Tuesday, May 19, 2009 3:36 AM
  • Thanks a lot :)
    Tuesday, May 19, 2009 3:48 AM
  • hi,

    You can also try a simple workaround by converting the width and height to a resource.....

    In App.xaml.cs you can try

    public App()
    
            {
    
                this.Resources["GridWidth"] = SystemParameters.WorkArea.Width - 370;
    
                this.Resources["GridHeight"] = SystemParameters.WorkArea.Width - 570;
    
            }

     

    and in window1.xaml you can write ....

    <Window x:Class="forims.Window1"
    
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    
        Title="Window1" WindowState="Maximized">
    
        <Grid Width="{DynamicResource GridWidth}" Height="{DynamicResource GridHeight}" Background="Red">
    
            
    
        </Grid>
    
    </Window>

    Hope it helps.


    Developer : Please mark the post as helpful or Answered if founded
    • Edited by Tarun Jindal Tuesday, May 19, 2009 8:16 AM
    • Proposed as answer by Tarun Jindal Tuesday, May 19, 2009 8:16 AM
    • Proposed as answer by Tao Liang Tuesday, May 19, 2009 8:17 AM
    • Marked as answer by LoveRiysa Tuesday, May 19, 2009 4:11 PM
    Tuesday, May 19, 2009 8:15 AM
  • Perfect :)

    Thank you!
    Tuesday, May 19, 2009 4:11 PM