Reputation: 387
I have following code where I am trying to display a property of my data context. But I see nothing when I run the application. I am a beginner to WPF. I maybe missing some minor setting somewhere.
If I remove DataContext="{Binding RelativeSource={RelativeSource Self}}"
and set the DataContext in code behind to MyPerson property and set
<ContentControl x:Name="myCC" Content="{Binding }"></ContentControl>
then everything works good.
<Window x:Class="WpfTestApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfTestApp"
Title="MainWindow" Height="350" Width="525"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Window.Resources>
<DataTemplate DataType="{x:Type local:Person}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"></ColumnDefinition>
<ColumnDefinition Width="200"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Content="_Name:" Grid.Row="0" Grid.Column="0"></Label>
<TextBox Text="{Binding Path=Name}" Grid.Column="1" Grid.Row="0"></TextBox>
<Label Content="_Age:" Grid.Row="1" Grid.Column="0"></Label>
<TextBox Text="{Binding Path=Age}" Grid.Column="1" Grid.Row="1"></TextBox>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid >
<ContentControl x:Name="myCC" Content="{Binding Path=MyPerson}"></ContentControl>
</Grid>
</Window>
public partial class MainWindow : Window
{
public Person MyPerson { get; set; }
public MainWindow()
{
InitializeComponent();
MyPerson = new Person { Age = 30, Name = "David" };
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button is clicked!!!");
}
}
public class Person : INotifyPropertyChanged
{
private int _age;
private string _name;
public int Age
{
get
{
return _age;
}
set
{
if (value != _age)
{
_age = value;
OnPropertyChanged("Age");
}
}
}
public string Name
{
get
{
return _name;
}
set
{
if (value != _name)
{
_name = value;
OnPropertyChanged("Name");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Upvotes: 0
Views: 98
Reputation: 453
OFF Topic but a simple example using MVVM pattern
Your Model Class
public class Person : INotifyPropertyChanged
{
private int _age;
private string _name;
public int Age
{
get
{
return _age;
}
set
{
if (value != _age)
{
_age = value;
OnPropertyChanged("Age");
}
}
}
public string Name
{
get
{
return _name;
}
set
{
if (value != _name)
{
_name = value;
OnPropertyChanged("Name");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
ViewModel is a Wrapper around the Model
public class PersonViewModel : INotifyPropertyChanged
{
private Person myPerson;
public Person MyPerson
{
get
{
if(myPerson == null)
myPerson=new Person { Age = 30, Name = "David" };
}
set
{
myPerson=value;
OnPropertyChanged("MyPerson");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
View and ViewModel Binding
<Window x:Class="WpfTestApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfTestApp"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:PersonViewModel />
</Window.DataContext>
<Window.Resources>
<DataTemplate DataType="{x:Type local:Person}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"></ColumnDefinition>
<ColumnDefinition Width="200"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Content="_Name:" Grid.Row="0" Grid.Column="0"></Label>
<TextBox Text="{Binding Path=Name}" Grid.Column="1" Grid.Row="0"></TextBox>
<Label Content="_Age:" Grid.Row="1" Grid.Column="0"></Label>
<TextBox Text="{Binding Path=Age}" Grid.Column="1" Grid.Row="1"></TextBox>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid >
<ContentControl x:Name="myCC" Content="{Binding Path=MyPerson}"></ContentControl>
</Grid>
Hope this Helps!!!!
Upvotes: 0
Reputation: 33364
You create MyPerson
after InitializeComponent
, which also sets DataContext
to MainWindow
as specified in XAML, and since your property does not raise INotifyPropertyChanged.PropertyChanged
event UI is never notified that it has changed. You can either implement INotifyPropertyChanged
on MainWindow
and raise PropertyChanged
event for MyPerson
property or if that property does not change, only its property changes, reverse the order
public MainWindow()
{
MyPerson = new Person { Age = 30, Name = "David" };
InitializeComponent();
}
Upvotes: 1