WPF-在表达式中使用静态资源

本文关键字:静态 资源 表达式 WPF- | 更新日期: 2023-09-27 18:24:06

我相信这是最简单的事情,但就我的一生而言,我似乎找不到解决方案。我正在为我的控件宽度定义一个双值,如下所示:

<sys:Double x:Key="dbl_controlPanelWidth">420</sys:Double>

现在我想将一个控件的宽度设置为该宽度的三分之一。有办法做到这一点吗?类似于:

<Button x:Name="btn_myButton" Width="{StaticResource dbl_controlPanelWidth} / 3"

谢谢。

WPF-在表达式中使用静态资源

您可以通过设置BindingExpressionSource属性来绑定高度。

  <Button x:Name="btn_myButton" 
            Width="{Binding Source={StaticResource dbl_controlPanelWidth}, 
                            Converter={converters:ScreenRatioConverter},
                            ConverterParameter='3'}"

通过使用so,您可以将任何静态源或ViewModel属性应用于它们。

您可以这样定义ScreenRatioConverter

    [ValueConversion(typeof(string), typeof(string))]
    public class ScreenRatioConverter : MarkupExtension, IValueConverter
    {
            private static ScreenRatioConverter _instance;
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            { 
                double size = System.Convert.ToDouble(value) / System.Convert.ToDouble(parameter, CultureInfo.InvariantCulture);
                return size.ToString("G0", CultureInfo.InvariantCulture);
            }
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            { 
                throw new NotImplementedException();
            }
            public override object ProvideValue(IServiceProvider serviceProvider)
            {
                return _instance ?? (_instance = new ScreenRatioConverter());
            }
        }

通过将因子值(3)作为参数,您可以随时重新调整width的大小。

我建议你看看这个答案:用xaml做数学此外,这个链接很短,而且切中要害:Xaml中的算术运算。

绑定中可以有表达式。

您需要做的是通过转换器将宽度绑定到资源,并将表达式编码到转换器中:

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is double)
        {
            return (double)value / 3;
        }
        return value;
    }

那么你的XAML就是:

<Button x:Name="btn_myButton" Width="{StaticResource dbl_controlPanelWidth}" />

由于我不是在添加新信息,而是在最后发布了一个我最终得到的解决方案,所以我会发布我自己问题的答案供其他人使用。我希望这很好。还没有那么有经验的SO。

所以。。。我从Niraj Doshi的代码开始,对它进行了一点扩展,以支持基本的算术运算(+、-、*、/),最后得到了以下代码:

 /// <summary>
    /// Converter for simple math operations. It should be bound to a source path, which has a number for its value.
    /// the parameter should be a string with a format of "N|xxxxx" (without quotes), where N is a number, the '|'
    /// sign is a separator and the second parameter (xxxxx) is a string defining the operation. Valid values are
    /// add, subtract, multiply and divide. Below example shows how a button's width is set to one third of the
    /// parent's canvas width:
    /// <Canvas x:Name="mainCanvas" Height="220" Width="260">
    ///     <Button x:Name="button1" 
    ///                Content="Button" 
    ///                Height="30" 
    ///                Canvas.Left="0" Canvas.Top="79" 
    ///                Width="{Binding ElementName=mainCanvas, Path=Width, 
    ///                                Converter={local:ScreenRatioConverter}, 
    ///                                ConverterParameter='3|divide'}"/>
    /// </Canvas>
    /// </summary>
    [ValueConversion(typeof(string), typeof(string))]
    public class ScreenRatioConverter : MarkupExtension, IValueConverter
    {
        private static ScreenRatioConverter _instance;
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string parameterString = parameter as string;
            string[] parameters = parameterString.Split(new char[] { '|' });
            double par1 = System.Convert.ToDouble(value);
            double par2 = System.Convert.ToDouble(parameters[0], CultureInfo.InvariantCulture);
            string operation = (string)parameters[1];
            double result = 20; //Default value to return if anything goes wrong.
            if (operation.Equals("add"))
            { result = par1 + par2; }
            else if (operation.Equals("subtract"))
            { result = par1 - par2; }
            else if (operation.Equals("multiply"))
            { result = par1 * par2; }
            else if (operation.Equals("divide"))
            { result = par1 / par2; }
            return result;
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
        //Needs to be overridden because of inheritance from MarkupExtension.
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return _instance ?? (_instance = new ScreenRatioConverter());
        }
    }
}

任何关于改进或使代码更安全/更干净/的评论。。。欢迎。