Origamer7
Origamer7

Reputation: 345

How can I modify from C# the value of an element which is define in a XAML DataTemplate?

I created a "WPF Application Project" in Visual Studio 2013.

I opened the "MainWindow.xaml" file and I wrote the following XAML code:

<Window x:Class="TestProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">

<Window.Resources>
    <DataTemplate x:Key="AlphaDataTemplate">
        <Label
            Name="LabelInDataTemplate"
            Content="Good morning!" />
    </DataTemplate>
</Window.Resources>

<Grid>
    <ContentPresenter
        Name="MyContentPresenter"
        ContentTemplate="{StaticResource AlphaDataTemplate}" />
    <Button
        Name="MyButton"
        Click="MyButton_OnClick"
        Content="Change the content of the Label in the DataTemplate"
        Width="320"
        Height="30" />
</Grid>

In this XAML file I created a "DataTemplate" which corresponds to the key "AlphaDataTemplate". The DataTmplate contains just one label with the name "LabelInDataTemplate" where I have hardcoded the "Good morning!" string in the "Content" attribute of the label.

Then I use created a "ContentPresenter" with the name "MyContentPresenter" and I pass as content the "DataTemplate" I previously created (AlphaDataTemplate).

As next step, I created a "Button" with the name "MyButton" and I have set a "Click" event called "MyButton_OnClick"

So far so good...!

The question comes now and actually in C# in the code behind file "MainWindow.xaml.cs". See the code below:

using System.Windows;

namespace TestProject { public partial class MainWindow : Window { public MainWindow() { InitializeComponent();

    }
    private void MyButton_OnClick(object sender, RoutedEventArgs e)
    {
        LabelInDataTemplate.Content = "Bye!";   // <-- Tha does not work.
    }
}

}

In this C# code behind file you can see the definition of the "Click" (MyButton_OnClick) event of the Button (MyButton) which appears in XAML.

What I am trying to do in this "Click" event, is to change the value of the "Content" of the "Label" (LabelInDataTemplate) which is in the DataTemplate (AlphaDataTemplate).

Unfortunately, that does not work.

I cannot actually access the "Name" (LabelInDataTemplate) of the "Label", because it is contained in the "DataTemplate" (AlphaDataTemplate)

If anyone has any idea, how could I modify from C# the value of an element which is define in a XAML DataTemplate, please give me feedback. I would really appreciate it.

Thank you in advance.

Upvotes: 0

Views: 1358

Answers (2)

Arun Selva Kumar
Arun Selva Kumar

Reputation: 2732

I strongly oppose your method of changing the content of label via DataTemplate, However your requirement is possible, but very subtle.

Code

private void MyButton_OnClick(object sender, RoutedEventArgs e)
{
    var alphaDataTemplate = this.Resources["AlphaDataTemplate"] as DataTemplate;
    var label = alphaDataTemplate.FindName("LabelInDataTemplate", MyContentPresenter) as Label;
    label.Content = "It Works";
}

Upvotes: 0

Nitin Purohit
Nitin Purohit

Reputation: 18578

Please learn MVVM and use proper DataBinding for this purpose. For sake of solving this problem:

  1. Implement INotifyPropertyChanged interface on your Window class and Define string property like below

    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
    
            DataContext = this;
    
        }
    
        public string _contentMsg;
        public string ContentMsg
        {
            get { return _contentMsg; }
            set 
            { 
                _contentMsg = value;
                RaisePropertyChanged("ContentMsg");
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(string propName)
        {
            if(PropertyChanged !=null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }
    
  2. In your xaml bind the ContentPresenter and update your DataTemplate label like

    <ContentPresenter
    Name="MyContentPresenter"
    Content = "{Binding ContentMsg}"
    ContentTemplate="{StaticResource AlphaDataTemplate}" />
    
    <DataTemplate x:Key="AlphaDataTemplate">
    <Label
        Name="LabelInDataTemplate"
        Content="{Binding}" />
    

  3. Now in click handler (I would use Commands here), set ContentMsg to whatever you want

     private void MyButton_OnClick(object sender, RoutedEventArgs e)
     {
          ContentMsg = "Bye!";  
     }
    

Upvotes: 0

Related Questions