Silverlight将databind int转换为无外观控件不起作用

问题描述

| 我正在使用一个非常简单的无外观控件,并且似乎无法使模板绑定之一正常工作。在控件中,我有两个依赖项属性一个是字符串有效,一个是int无效。 csharp代码如下所示:
using System;
using System.Windows;
using System.Windows.Controls;

namespace ControlDemo
{
    public class TextControlLookless : Control
    {
        #region Title

        public static readonly DependencyProperty ChartTitleProperty =
            DependencyProperty.Register(\"ChartTitle\",typeof(string),typeof(TextControlLookless),null);


        public String ChartTitle
        {
            get { return (string)GetValue(ChartTitleProperty); }
            set
            {
                SetValue(ChartTitleProperty,value);
            }
        }

        #endregion

        #region Value

        public static readonly DependencyProperty ChartValueProperty =
            DependencyProperty.Register(\"ChartValue\",typeof(int),null);


        public int ChartValue
        {
            get { return (int)GetValue(ChartValueProperty); }
            set
            {
                SetValue(ChartValueProperty,value);
            }
        }

        #endregion

        #region ctor

        public TextControlLookless()
        {
            this.DefaultStyleKey = typeof(TextControlLookless);
        }

        #endregion

    }
}
控件的xaml如下所示:
<ResourceDictionary
xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" 
xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"
xmlns:local=\"clr-namespace:ControlDemo\">

<Style targettype=\"local:TextControlLookless\">
    <Setter Property=\"ChartTitle\" Value=\"Set Title\" />
    <Setter Property=\"ChartValue\" Value=\"1\" />

    <Setter Property=\"Template\">
        <Setter.Value>
            <ControlTemplate targettype=\"local:TextControlLookless\">
                <Grid x:Name=\"Root\">
                    <Border BorderBrush=\"Black\" BorderThickness=\"2\">
                        <Grid>
                            <Grid.RowDeFinitions>
                                <RowDeFinition Height=\"Auto\" />
                                <RowDeFinition Height=\"Auto\" />
                                <RowDeFinition />
                            </Grid.RowDeFinitions>
                            <TextBlock Text=\"{TemplateBinding ChartTitle}\" />
                            <TextBlock Text=\"{TemplateBinding ChartValue}\" Grid.Row=\"1\" />
                        </Grid>
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
当我将其放在页面上时,可以看到ChartTitle(“设置标题”或我设置的任何内容),但ChartValue从未显示。如果我将其类型更改为字符串,则确实会显示它,因此我必须缺少某些内容。     

解决方法

问题在于
TemplateBinding
比than3ѭ更原始。 “ 3”是一个实际的类,它包括一些有用的功能,包括在其他数据类型之间来回隐式转换字符串。
TemplateBinding
纯粹是一个标记指令,而在您情况下,关键的是不会为您执行类型转换。因此,绑定到
TextBlock
Text
属性的依赖项属性必须是字符串。 您有两种选择: 一种选择是改为使用TemplateBinding给
TextBlock
命名并在
ChartValue
属性更改后的回调中分配其ѭ6assign:-
    #region Value

    public static readonly DependencyProperty ChartValueProperty =
        DependencyProperty.Register(\"ChartValue\",typeof(int),typeof(TextControlLookless),new PropertyMetadata(0,OnChartValuePropertyChanged));

    private static void OnChartValuePropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
    {
        TextControlLookless source = d as TextControlLookless;
        source.Refresh();
    }


    public int ChartValue
    {
        get { return (int)GetValue(ChartValueProperty); }
        set
        {
            SetValue(ChartValueProperty,value);
        }
    }

    #endregion

    private TextBlock txtChartValue { get; set; }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        txtChartValue = GetTemplateChild(\"txtChartValue\") as TextBlock;
        Refresh();
    }

    private void Refresh()
    {
        if (txtChartValue != null)
        {
            txtChartValue.Text = ChartValue.ToString();
        }
    }
xaml看起来像:
    <TextBlock x:Name=\"txtChartValue\" Grid.Row=\"1\" />
另一种选择是为字符串类型的值创建一个私有依赖项属性:
        #region Value

        public static readonly DependencyProperty ChartValueProperty =
            DependencyProperty.Register(\"ChartValue\",OnChartValuePropertyChanged));

        private static void OnChartValuePropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
        {
            d.SetValue(ChartValueStrProperty,e.NewValue.ToString());
        }

        private static readonly DependencyProperty ChartValueStrProperty =
            DependencyProperty.Register(\"ChartValueStr\",typeof(string),new PropertyMetadata(\"0\"));

        public int ChartValue
        {
            get { return (int)GetValue(ChartValueProperty); }
            set
            {
                SetValue(ChartValueProperty,value);
            }
        }

        #endregion
xaml看起来像:
        <TextBlock Text=\"{TemplateBinding ChartValueStr}\" Grid.Row=\"1\" />
注意,“ 15”是私有的,我没有费心创建一个标准的.NET属性来覆盖它。
TemplateBinding
实际上使用您为后缀指定的属性名称带有\“ Property \”,然后在目标类型上查找静态字段。 两种方法都有其优点和缺点。第一种方法是更通用的模式,但是需要更多的代码并且灵活性较低(显示值的控件必须是TextBlock)。第二个更灵活,使用更少的代码,但是有些不合常规。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...