访问 IvalueConverter 中的用户控件属性 |银光4

发布于 2024-12-08 14:57:20 字数 2987 浏览 0 评论 0原文

我正在尝试编写一个代表水箱的自定义 silverlight 控件。它有两个依赖属性:liquidLevel 和liquidCapacity,我想将这两个参数与gradientBrush 一起传递到转换器中。这个想法是转换器将根据液位和容量进行计算,并调整画笔上的梯度停止点以给出液体上升和下降的外观。

我的坦克有一个“窗口”,它只是一个矩形和gradientBrush,到目前为止我已经得到了这个

我的控件模板

<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 *

使用xaml中的控件(最终我想绑定这些属性)

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

和转换器

   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;
        }

我现在所在的位置是我想要从我的转换器访问第二个控制属性liquidCapacity,以便我可以计算水箱已满的百分比。我尝试过将 LiquidCapacity 作为转换器参数传递,但如果可能的话,我无法弄清楚语法(我对 silverlight 还很陌生)。

现在我已经做到了这一点,我想我可以创建一个名为 fillpercentage 的单一依赖属性,并在最终的视图模型中执行此计算,但随着数据在其中的组织方式,我很确定我将面临一系列全新的挑战如果我尝试这个。对我来说,能够在 xaml 中对液体容量进行硬编码,并将液体水平绑定到视图模型似乎更容易管理。视图模型将从数据库中提取一堆值并放入可观察字典中,其中一个是液体水平,因此我认为将液体水平直接绑定到可观察字典会更容易,而不是尝试将其转换在绑定视图模型之前将其设置为“fillpercentage”。

另外,我很顽固,为了我的教育利益,有人知道我提议做的事情是否可行。如果是这样,正确的方法是什么?

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 what I proposed to do is possible. If so, what the correct way to go about it ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心安伴我暖 2024-12-15 14:57:20

当你说你

已尝试将 LiquidCapacity 作为转换器参数传递

我怀疑您正在尝试执行类似的操作,

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

这将不起作用。一个绑定不能包含在另一个绑定内。

就我个人而言,我不会使用转换器来完成您想要做的事情。相反,我会在 LiquidTank 控件的代码中添加一个方法来调整 LinearGradientBrush 的渐变停止点。然后,我将 PropertyChangedCallback 添加到 LiquidTank 控件的 LiquidLevelLiquidCapacity 依赖属性并调用此方法从这些回调中。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文