WPF数据绑定没有调用!

时间:2009-01-03 17:47:15

标签: wpf data-binding

我有UserControl,其中包含TextBox和Button控件。按钮打开FileDialog,用户选择该文件。所选文件将传输到FileName属性,该属性是依赖项属性。由于某种原因,TextBox未绑定到此属性。这是代码:

<UserControl x:Class="WPF3D.FileInputBox"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300" x:Name="root">
    <Grid>

        <StackPanel>            
        <TextBox Name="txtFile" Text="{Binding FileName, ElementName=root}" Width="300" Height="20" />
        <Button Content="Select File" Width="100" Height="20" Click="SelectFile"  /> 
        </StackPanel>



    </Grid>
</UserControl>

以下是UserControl.cs文件的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using System.Windows.Markup;

namespace WPF3D
{
    [ContentProperty("FileName")]
    public partial class FileInputBox : UserControl
    {
        public static readonly DependencyProperty FileNameProperty = DependencyProperty.Register("FileName",
                                                                                                 typeof (String),
                                                                                                 typeof (FileInputBox));


        public event EventHandler<EventArgs> FileNameChanged; 

        public FileInputBox()
        {
            InitializeComponent();
            txtFile.TextChanged += new TextChangedEventHandler(txtFile_TextChanged);
        }

        void txtFile_TextChanged(object sender, TextChangedEventArgs e)
        {
            e.Handled = true; 
            if(FileNameChanged != null)
            {
                FileNameChanged(this, EventArgs.Empty); 
            }

        }

        public string FileName
        {
            get { return (string) GetValue(FileNameProperty); }
            set { SetValue(FileNameProperty,value);}
        }


        private void SelectFile(object sender, RoutedEventArgs e)
        {
            // select the file 
            var fileDialog = new OpenFileDialog();
            fileDialog.ShowDialog();

            this.FileName = fileDialog.FileName;
        }

        protected override void OnContentChanged(object oldContent, object newContent)
        {
            if(oldContent != null)
                throw new InvalidOperationException("You can't change the content"); 
        }
    }
}

2 个答案:

答案 0 :(得分:3)

我认为这只是一个范围问题,调试窗口中的输出很明显:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=root'. BindingExpression:Path=FileName; DataItem=null; target element is 'TextBox' (Name='txtFile'); target property is 'Text' (type 'String')

如果你只是改成它,它可以正常工作:

<UserControl x:Class="TestApp.FileInputBox"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">
    <Grid x:Name="_grid">
        <StackPanel>
            <TextBox Name="txtFile" Text="{Binding FileName}" Width="300" Height="20" />
            <Button Content="Select File" Width="100" Height="20" Click="SelectFile"  />
        </StackPanel>
    </Grid>
</UserControl>

代码隐藏的重要部分:

public FileInputBox()
{
    InitializeComponent();
    txtFile.TextChanged += new TextChangedEventHandler(txtFile_TextChanged);
    _grid.DataContext = this;
}

请注意,在DataContext而不是Grid上设置UserControl是有意的。如果您在UserControl级别执行此操作,则只需更改DataContext的{​​{1}}即可让控件的使用者破坏您的绑定。

答案 1 :(得分:0)

使用以下链接得到答案:

http://geekswithblogs.net/thibbard/archive/2008/04/22/wpf-custom-control-dependency-property-gotcha.aspx

这似乎是WPF框架的一个蹩脚限制!