WPF Databinding won't ring!

I have a UserControl that contains a TextBox and a Button control. The button opens the FileDialog and the user selects the file. The selected file is transferred to the FileName property, which is a dependency property. For some reason, the TextBox is not bound to this property. Here is the code:

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

      

And here is the code for the UserControl.cs file:

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

      

+1


source to share


2 answers


I think this is just a problem, as evidenced by this output in the debug window:

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')

      

If you just change it to this, it works great:

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

      



And the important part of the code:

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

      

Please note that the installation is DataContext

in Grid

, not UserControl

intentional. If you do this at the level UserControl

, consumers of your control can break your bindings simply by changing DataContext

yours UserControl

.

+3


source


Got a response using the following link:

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



It seems to be a lame limitation of the WPF framework!

0


source







All Articles