In My WPF C# application I created a TextBox that shows the names of a Customer. The names Consists of FirstName, MiddleName and LastName. What I wanted to Implement is that the TextBox to Show FullName (which is the the 3 names joined together, separated by space) when it doesn’t have a Keyboard Focus and to show the 3 names in 3 different textboxes inside the Fullname TextBox when the FullName TextBox gets Keyboard Focus. I tried my best and Implemented the Control but what I was unable to implement was to get the data and also save the data changes.

Here is my DATABASE SCRIPT:

USE [MyDB]
GO
/****** Object:  Table [dbo].[Customers]    Script Date: 12/7/2023 7:57:47 AM ******/
SET ANSI_NULLS ON
GO  
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Customers](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [FirstName] [nvarchar](50) NULL,
    [MiddleName] [nvarchar](50) NULL,
    [LastName] [nvarchar](50) NULL,
 CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[Customers] ON 
GO
INSERT [dbo].[Customers] ([ID], [FirstName], [MiddleName], [LastName]) VALUES (1, N'Dees', N'Niis', N'Muus')
GO
INSERT [dbo].[Customers] ([ID], [FirstName], [MiddleName], [LastName]) VALUES (2, N'Jiis', N'Kiss', N'Juss')
GO
INSERT [dbo].[Customers] ([ID], [FirstName], [MiddleName], [LastName]) VALUES (3, N'Nyuus', N'Nyap', N'Kip')
GO
SET IDENTITY_INSERT [dbo].[Customers] OFF
GO

enter image description here

And here are the sample codes in github

2

There are 2 best solutions below

2
mm8 On BEST ANSWER

Here is what you need to do to make your sample app work:

  1. Bind the model object to the ContentControl:

     <ContentControl Style="{StaticResource MultiTextBox}"
                     materialdesign:HintAssist.Hint="FullName"
                     MinWidth="300"
                     MaxWidth="400"
                     VerticalAlignment="Bottom"
                     Content="{Binding}"/>
    
  2. Set the Mode of the binding to the FullName property to OneWay:

     <Trigger Property="IsKeyboardFocusWithin" Value="False">
         <Setter TargetName="dummyTextBox" Property="Text" Value="{Binding Path=FullName, Mode=OneWay}"/>
     </Trigger>
    
  3. Raise the PropertyChanged event for the FullName property in the OnChange() method of the CustomerModel:

     private void OnChange()
     {
         _FullName = FirstName + " " + MiddleName + " " + LastName;
         OnPropertyChanged(nameof(FullName));
     }
    
2
BionicCode On

You are overriding the correct DataContext of the ContentControl with a wrong value. That's why your bindings won't resolve.

The value of ContentControl.Content property is the full name:

<ContentControl Content="{Binding Path=FullName}" />

The important part to know is that the DataContext of the ContentControl is inherited from the Window and is the therefore CustomerModel instance.

So far so good. But inside your ControlTemplate you overwrite the inherited DataContext and set it to the value of the Content property. This value is the full name (from CustomerModel.FullName):

<ControlTemplate x:Key="MultiTextBoxTemplate" TargetType="ContentControl">
  <Grid DataContext="{TemplateBinding Content}">

To make it work simply don't overwrite the (correct) DataContext:

<ControlTemplate x:Key="MultiTextBoxTemplate" TargetType="ContentControl">

  <!-- DataContext is inherited from the Window and is the CustomerModel -->
  <Grid>

Now your bindings will successfully use the CustomerModel as binding source.