开发者

Accessing user control properties in IvalueConverter | silverlight 4

开发者 https://www.devze.com 2023-04-11 22:14 出处:网络
I am trying to write a custom silverlight control which represents a water tank. It has two dependency properties, liquidLevel and liquidCapacity, and I want to pass both of these parameters into a co

I am trying to write a custom silverlight control which represents a water tank. It has two dependency properties, liquidLevel and liquidCapacity, and I want to pass both of these parameters into a converter along with a gradientBrush. The idea is the converter will perform a calcuation based on the liquidlevel and capacity and adjust the gradient stops on the brush to give the appearance of liquid rising and falling.

my tank has a "window" which is just a rectangle and gradientBrush, so far I have got this

My control template

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MoreControls;assembly=MoreControls"
    xmlns:assets="clr-namespace:MoreControls.Assets">

   <LinearGradientBrush x:Name="LiquidLevelTankWindow" StartPoint="0.469,0.997" EndPoint="0.487,0.013">
        <GradientStop Color="#FF1010F1" Offset="0.0"/>
        <GradientStop Color="#FF5555FB" Offset="0.55"/>
        <GradientStop Color="#FFE4E4F1" Offset="0.6"/>
         <GradientStop Color="#FFFAFAFD" Offset="1"/>
   </LinearGradientBrush>  

   <assets:LiquidLevelBrushConverter x:Name="LiquidLevelBrushConverter" levelBrush="{StaticResource LiquidLevelTankWindow}"/>

    <Style x:Key="Liquid" TargetType="local:LiquidTank">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:LiquidTank">

                // * parts of the control here *

                // the part of the control im interested in
                <Rectangle x:Name="TankWindow" Width="32.3827" Height="64" Canvas.Left="27" Canvas.Top="42" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000310" 
                                    Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LiquidLevel, Converter={StaticResource LiquidLevelBrushConverter}}" />

               // * rest of control template *

Using the control in xaml (eventually I want to bind these properties)

     <local:LiquidTank Style="{StaticResource Liquid}" LiquidCapacity="100" LiquidLevel="50"/>

and the converter

   public class LiquidLevelBrushConverter : IValueConverter
    {
        public LinearGradientBrush levelBrush { get; set; }  

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
        //I can access the liquid level parameter here           
            double level = 0;
            double.TryParse(value.ToString(), out level);

            GradientStopCollection gsc = levelBrush.GradientStops;
            //some logic to alter gradient stops   

            return null;
        }

Where I am now is that I want to access the second control property liquidCapacity from my converter so I can calculate the percentage of the tank that is full. I have tried passing liquidCapacity through as a converter parameter but if that's possible I cant figure out the syntax (I'm pretty new to silverlight).

Now that i've got this far im thinking I could have created a single dependancyproperty called fillpercentage, and perform this calculation in the eventual viewmodel, but with the way data will organised in there im pretty sure I will have a whole new set of challenges if I try this. It seems more manageable to me to be able to hardcode the liquidcapacity in the xaml, and bind the liquidlevel to the viewmodel. The view model will being pulling a bunch of values out of a database and into an observable dictionary, one of those being the liquidlevel, so it would be much easier I think to bind liquidlevel directly to the observable dictionary, rather than try and convert it to a "fillpercentage" in the view model before binding it.

Plus im pretty stubborn and in the interest of my education does anyone know if wha开发者_如何转开发t I proposed to do is possible. If so, what the correct way to go about it ?


When you say that you

have tried passing liquidCapacity through as a converter parameter

I suspect you're trying to do something like

<Rectangle Fill="{Binding Path=LiquidLevel, ConverterParameter={Binding Path=LiquidCapacity} ...}" />

This won't work. You can't have a binding inside another binding.

Personally, I wouldn't use a converter for what you're trying to do. Instead, I'd add a method to adjust the gradient stops of the LinearGradientBrush to the code of the LiquidTank control. I'd then add PropertyChangedCallbacks to the LiquidLevel and LiquidCapacity dependency properties of the LiquidTank control and call this method from within these callbacks.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号