Comment définir la valeur de la ressource dynamique basée sur une autre ressource dynamique?

StackOverflow https://stackoverflow.com/questions/1796400

  •  22-09-2019
  •  | 
  •  

Question

Est-il possible d'attribuer une valeur à une ressource dynamique d'une autre ressource dynamique?
Par exemple

<sys:Double x:Key="ButtonWidth">48</sys:Double>
<sys:Double x:Key="SmallButtonWidth"> ButtonWidth / 2 </sys:Double>
Était-ce utile?

La solution

Il est possible de transformer une valeur en utilisant une coutume MarkupExtension .

par exemple.

<Window.Resources xmlns:ms="clr-namespace:WpfApplication1.MathShit">
    <sys:Double x:Key="ButtonWidth">48</sys:Double>
    <ms:Calculation x:Key="SmallButtonWidth">
        <ms:Product Operand1="{ms:Value {StaticResource ButtonWidth}}"
                    Operand2="0.5" />
    </ms:Calculation>
</Window.Resources>
namespace WpfApplication1.MathShit
{
    [ContentProperty("Expression")]
    public class Calculation : MarkupExtension
    {
        public IExpression Expression { get; set; }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (Expression == null) throw new Exception("Expression cannot be null.");

            return Expression.CalculateValue();
        }
    }

    [TypeConverter(typeof(ExpressionConverter))]
    public interface IExpression
    {
        double CalculateValue();
    }

    public abstract class BinaryOperation : IExpression
    {
        public IExpression Operand1 { get; set; }
        public IExpression Operand2 { get; set; }

        public double CalculateValue()
        {
            if (Operand1 == null) throw new Exception("Operand1 cannot be null.");
            if (Operand2 == null) throw new Exception("Operand2 cannot be null.");

            return CalculateBinaryOperation();
        }

        protected abstract double CalculateBinaryOperation();
    }
    public class Sum : BinaryOperation
    {
        protected override double CalculateBinaryOperation()
        {
            return Operand1.CalculateValue() + Operand2.CalculateValue();
        }
    }
    public class Product : BinaryOperation
    {
        protected override double CalculateBinaryOperation()
        {
            return Operand1.CalculateValue() * Operand2.CalculateValue();
        }
    }
    public class Value : MarkupExtension, IExpression
    {
        public double? Double { get; set; }

        public Value() { }
        public Value(double @double)
            : this()
        {
            this.Double = @double;
        }

        public double CalculateValue()
        {
            if (Double == null) throw new Exception("Double");

            return Double.Value;
        }

        // Allows easy object instantiation in XAML attributes. (Result of StaticResource is not piped through ExpressionConverter.)
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return this;
        }
    }

    public class ExpressionConverter : DoubleConverter
    {
        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            var doubleValue = (double)base.ConvertFrom(context, culture, value);
            return (IExpression)new Value(doubleValue);
        }

        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            var val = (Value)value;
            return base.ConvertTo(context, culture, val.CalculateValue(), destinationType);
        }
    }
}

Avec cela, vous pouvez construire des arbres d'expression arbitraires (ce qui est beaucoup plus facile que l'analyse syntaxique des chaînes de mathématiques que vous pouvez faire aussi bien bien sûr si vous ne me dérange pas la peine).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top