DependencyProperty ...可以设置,但不能通过绑定获取值

时间:2011-10-13 15:20:27

标签: wpf xaml

我有一个Window,包含一个UserControl'TemplateEditor'。 (缩短的)TemplateEditor XAML是:

<UserControl x:Class="xxx.Windows.Core.Controls.TemplateEditor"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             x:Name="userControl">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBox Grid.Row="1" x:Name="textBox" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" />
    </Grid>
</UserControl>

我希望能够通过TemplateEditor将数据绑定到TextBox“textBox”中。我正在使用DependencyProperty来掩盖代码隐藏中的TextBox:

namespace xxx.Windows.Core.Controls
{
    public partial class TemplateEditor : UserControl 
    {
        public string Text
        {
            get 
            { 
                string s=(string)GetValue(TextProperty);
                return s;
            }
            set 
            {
                if (Text != value)
                { 
                    SetValue(TextProperty, value);
                }
            }
        }

        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(TemplateEditor),new PropertyMetadata(null,Text_PropertyChanged));

        public TemplateEditor()
        {
            InitializeComponent();
        }

        private static void Text_PropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            ((TemplateEditor)source).textBox.Text = (string)e.NewValue;
        } 
    }
}

因此,您可以看到我有一个DependencyProperty文本,我有一个回调来获取绑定所做的更改(例如,从ViewModel)并应用于TextBox值。

这很有效。

问题是,我似乎无法反向进行绑定工作,即。从Text属性(以及TextBox)中取回值,然后返回绑定使用者(ViewModel)。我调试了调用GetValue(TextProperty)并返回正确的值,以便DP字典正确更新。

在父窗口的XAML中给出以下绑定:

<src:ApplicationWindowBase x:Class="xxx.Windows.Client.Filing"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:src="clr-namespace:xxx.Windows.Core;assembly=MIGTurbo1.Windows.Core"
        xmlns:viewmodel="clr-namespace:xxx.Windows.Client.ViewModel"
        xmlns:converters="clr-namespace:xxx.Windows.Client.Converters"
        xmlns:xxx_Windows_Core_Controls="clr-namespace:xxx.Windows.Core.Controls;assembly=xxx.Windows.Core" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        mc:Ignorable="d" 
        Title="File Item(s)" Height="450" Width="550" ShowInTaskbar="False">
    <src:ApplicationWindowBase.Resources>
        <viewmodel:ViewModelLocator x:Key="ViewModelLocator" d:IsDataSource="True"/>
        <converters:FileableItemNameStringConverter x:Key="fileableItemNameStringConverter" />
        <converters:FileableItemTypeStringConverter x:Key="fileableItemTypeStringConverter" />
        <converters:FileableItemMetaDataStringConverter x:Key="fileableItemMetaDataStringConverter" />
        <converters:FileableItemIconConverter x:Key="fileableItemIconConverter" />
    </src:ApplicationWindowBase.Resources>
    <src:ApplicationWindowBase.DataContext>
        <Binding Mode="OneWay" Path="Filing" Source="{StaticResource ViewModelLocator}"/>
    </src:ApplicationWindowBase.DataContext>
    <Grid>
       <!-- SNIP -->
    <xxx_Windows_Core_Controls:TemplateEditor Grid.Column="1" Grid.Row="1" Margin="0" Text="{Binding Comment, Mode=TwoWay}" d:LayoutOverrides="Width, Height"/>
       <!-- SNIP -->
</src:ApplicationWindowBase>

我正在使用MVVM Light,ViewModel正确绑定。还有其他控制/字段绑定(省略)可以正常工作。问题是Comment ViewModel属性上的Text属性绑定不起作用。我可以设置好(即在ViewModel中设置值,然后绑定)但是Text中用户输入的值永远不会进入ViewModel Comments属性。

我做错了什么?

2 个答案:

答案 0 :(得分:2)

试试这个:

<TextBox Text="{Binding ElementName=userControl,Path=Text,Mode=TwoWay}" />

并删除处理程序。

答案 1 :(得分:0)

好的,典型的StackOverflow usage pattern已被采纳。

我意识到我正在单向写这个,添加了一个TextChanged事件处理程序来更新依赖属性。

public partial class TemplateEditor : UserControl 
{

    public string Text
    {
        get 
        { 
            string s=(string)GetValue(TextProperty);
            return s;
        }
        set 
        {
            if (Text != value)
            { 
                SetValue(TextProperty, value);
            }
        }
    }

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(TemplateEditor),new PropertyMetadata(null,Text_PropertyChanged));

    public TemplateEditor()
    {
        InitializeComponent();

        textBox.TextChanged += new TextChangedEventHandler(textBox_TextChanged);
    }

    private static void Text_PropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        ((TemplateEditor)source).textBox.Text = (string)e.NewValue;
    }


    void textBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        Text = textBox.Text;
    }
}

感谢您的时间和道歉。 :)