1

It is simple thing that works everywhere instead of TextBox.Text without any reasons. What I need is just to get updated Text property of textbox when DataContext changed. There is a DataGrid and another control behind it to show details about row. So when user click's on row I am obtain data object from grid's row and show its details in this details control. Details control contains just propertyName and value control. I.e. textblock and textbox. ANY property of textblock or textbox are updated on changing DataContext except Text in textbox. I've break my head already. The main problem is textbox won't updated after I've changed it. And it works fine if move textbox outside control to the details control (parent)

The property-Value control:

    <DockPanel x:Class="UserControls.PropertySectionControl"
                 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="_propertyDockPanel"
                 HorizontalAlignment="Stretch"  Margin="0 5 0 0"
                 d:DesignHeight="300" d:DesignWidth="300">

        <TextBlock  Text="{Binding Path=Property, ElementName=_propertyDockPanel}" TextWrapping="Wrap"/>
        <TextBox              
  Text="{Binding Path=Value, ElementName=_propertyDockPanel, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                 IsReadOnly="{Binding Path=IsReadOnly, ElementName=_propertyDockPanel}"             
                 TextAlignment="Right" Foreground="Gray" TextWrapping="Wrap" Width="120" Height="20" HorizontalAlignment="Right" Margin="0 0 15 0"
                 ToolTip="{Binding Value, ElementName=_propertyDockPanel}" Template="{StaticResource _inspectorValueTemplate}"
                 LostFocus="_textBoxValue_LostFocus" GotFocus="_textBoxValue_LostFocus" KeyDown="_textBoxValue_KeyDown" TextChanged="_textBoxValue_TextChanged"         
             />
    </DockPanel>

And here is how it is used in details control:

<userControls:PropertySectionControl Property="Total" Value="{Binding OrderCharges.Total}" IsReadOnly="True"/>

As you can see, in PropertySectionControl there is also binding ToolTip to Value which is works on DataContext changed! But for TextBox.Text is not. What is this?

UPD: PropertySectionControl.cs

public partial class PropertySectionControl : DockPanel
    {
        public string Property
        {
            get { return (string)GetValue(PropertyProperty); }
            set { SetValue(PropertyProperty, value); }
        }

        public string Value
        {
            get { return (string)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }


        public bool IsReadOnly
        {
            get { return (bool)GetValue(IsReadOnlyProperty); }
            set { SetValue(IsReadOnlyProperty, value); }
        }

        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(string), typeof(PropertySectionControl), new PropertyMetadata(""));


        public static readonly DependencyProperty PropertyProperty =
            DependencyProperty.Register("Property", typeof(string), typeof(PropertySectionControl), new PropertyMetadata(""));


        public static readonly DependencyProperty IsReadOnlyProperty =
                    DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(PropertySectionControl), new PropertyMetadata(false));


        public PropertySectionControl()
        {
            InitializeComponent();
        }


        /// <summary>
        /// Static event handler is for use in Inspector control as well
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public static void TextBox_LostOrGotFocus(object sender, RoutedEventArgs e)
        {
            var textBox = sender as TextBox;
            if (textBox.IsFocused)
            {
                textBox.TextAlignment = TextAlignment.Left;
                textBox.SelectAll();
            }
            else
            {
                textBox.TextAlignment = TextAlignment.Right;                
            }
        }

        public static void TextBox_KeyDown(object sender, KeyEventArgs e)
        {
            var textBox = sender as TextBox;
            if (e.Key == Key.Enter)
            {
                textBox.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
            }

            else if (e.Key == Key.Escape)
            {
                int i = 0;
                do
                {
                    textBox.MoveFocus(new TraversalRequest(FocusNavigationDirection.Right));

                } while (!(Keyboard.FocusedElement is TextBoxBase) && ++i < 5);      // prevent infinite loop

                Keyboard.ClearFocus();
            }
        }

        public static void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            var textBox = sender as TextBox;
            textBox.Height = 20;
            for (int i = 2; i <= textBox.LineCount; i++)
                textBox.Height += 14;
        }

        private void _textBoxValue_LostFocus(object sender, RoutedEventArgs e)
        {
            TextBox_LostOrGotFocus(sender, e);
        }

        private void _textBoxValue_KeyDown(object sender, KeyEventArgs e)
        {
            TextBox_KeyDown(sender, e);
        }

        private void _textBoxValue_TextChanged(object sender, TextChangedEventArgs e)
        {
            TextBox_TextChanged(sender, e);
        }
    }
5
  • 1
    Im quite sure, Dockpanel has no Property Value Commented Jun 20, 2016 at 12:46
  • 2
    Thanks for fast feedback, but it has. As mentioned, binding ToolTip to Value are ok Commented Jun 20, 2016 at 12:50
  • Try with get { return GetValue(PropertyProperty).ToString(); } Commented Jun 20, 2016 at 12:55
  • Should you have Mode=TwoWay in your TextBox binding? If it's just a tooltip you shouldn't be putting values back into your DataGrid? Commented Jun 20, 2016 at 12:56
  • Thanks for the tip. I've update the question. The main problem is textbox won't update further after i've edited it. So it updates ok before first edit. Commented Jun 20, 2016 at 12:58

1 Answer 1

1

Just guessing:

1) That textbox has a textchanged eventhandler set. Check if that handler works OK. Try to comment it out ans see if it changes anything. I.e. maybe it gets fired during the data update from model and maybe it throws an exception and binding is aborted in the meantime?

1a) run in VS in Debug mode and check 'Output' window. See if there is anything reported like:

  • first chance exceptions
  • binding errors

important especially if they show up when you try editing the textbox for the first time

2) Also, whenever a binding magically stops working, be sure to check if the binding is still in place. I see you are using a direct access to the controls from code-behind (like textbox.Height += ..). This is an easy way to break the bindings. If you ever anywhere ran one of these lines:

textBox.Text = ""
textBox.Text = "foo"
textBox.Text = john.name
textBox.Text += "."

these may have a high chance of unsetting your bindings on Text on that textbox. I don't see any such line in the code you provided, but maybe you have it elsewhere.

You can easily check if the binding is still inact by running:

object realvalue = textBox.ReadLocalValue(TextBox.TextProperty);

now if the realvalue is null, or string, or anything other than a Binding object - that means that something accessed the textbox and replaced the binding with a concrete constant value, and you need to find and correct that so that .Text is not assigned and instead of that the Value property of source object (customdockpanel) is changed.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.