I want to Bind ChildProperty to the TextBox in xaml.
XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="ChildProperty" Grid.Column="0" Grid.Row="0"/>
<TextBox Text="{Binding Path=ChildProperty}" Grid.Column="1" Grid.Row="0" Width="50"/>
<TextBlock Text="ParentProperty" Grid.Column="0" Grid.Row="1"/>
<TextBox Text="{Binding Path=ParentProperty}" Grid.Column="1" Grid.Row="1" Width="50"/>
</Grid>
DataContext:
public NotifyParentChangePropertyInChildClass()
{
InitializeComponent();
this.DataContext = new ParentClass();
}
Parent & Child Class:
public class ParentClass :INotifyPropertyChanged
{
private int parentProperty;
public int ParentProperty
{
get { return parentProperty; }
set
{
parentProperty = value;
RaisePropertyChanged("ParentProperty");
}
}
public ParentClass()
{
ChildClass obj = new ChildClass();
obj.ChildProperty = 100;
parentProperty = 200;
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class ChildClass : INotifyPropertyChanged
{
private int childProperty;
public int ChildProperty
{
get { return childProperty; }
set
{
childProperty = value;
RaisePropertyChanged("ChildProperty");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
When I run above code, In out put window Message "System.Windows.Data Error: 40 : BindingExpression path error: 'ChildProperty' property not found on 'object' ''ParentClass' (HashCode=59593954)'. BindingExpression:Path=ChildProperty; DataItem='ParentClass' (HashCode=59593954); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String')"
The Error you are getting is right. You had set the DataContext to be ParentClass, whereas you are setting the binding property from ChildClass. You can only have one DataContext. To use both the properties you can define the properties in same class or derive from one and use the child class as datacontext.
Define property of Type ChildClass in ParentClass as below:
ChildClass _childClass;
public ChildClass ChildClass
{
get { return _childClass; }
set { _childClass = value; RaisePropertyChanged("ChildClass"); }
}
and in constructor of ParentClass initialize instance of _childClass.
Change the binding of textbox as:
<TextBox Text="{Binding Path=**ChildClass.ChildProperty**}" Grid.Column="1" Grid.Row="0" Width="50"/>
Thanks
Related
I am new to object binding and I don' succeed to make it work.
I have a xaml window with the following textbox:
<Grid x:Name="gr_main" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="180,65,0,0" DataContext="{Binding currentproj}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox Grid.Row="0" Grid.Column="2" x:Name="txt_localdir" Height="25" TextWrapping="Wrap" Width="247" IsEnabled="False" Text="{Binding Path=Localdir, UpdateSourceTrigger=PropertyChanged}"/>
In the cs code of the main window, I define an instance of my Project class, called currentproj, as follows:
public partial class MainWindow : Window{
Project currentproj;
public MainWindow()
{
currentproj = new Project();
InitializeComponent();
}}
The project class (defined in a Project.cs file) is as follows:
public partial class Project : Component, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private string _localdir;
public string Localdir
{
get { return _localdir; }
set
{
if (value != _localdir)
{
_localdir = value;
NotifyPropertyChanged("Localdir");
}
}
}
public Project()
{
InitializeComponent();
}
public Project(IContainer container)
{
container.Add(this);
InitializeComponent();
}}
However, even if I am binding the textbox.text attribute to the Localdir path of the currentproj object, the textbox is never updated. I see the PropertyChanged event is alwais null when I set the value of Localdir, but I don't understand why.
Data binding works on the DataContext. The Grid's DataContext is not set correctly, this should be removed.
so the Grid definition should be:
<Grid x:Name="gr_main" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="180,65,0,0">
Setting the Window DataContext to currentProj is done by:
public partial class MainWindow : Window{
Project currentproj;
public MainWindow()
{
currentproj = new Project();
DataContext = currentproj;
InitializeComponent();
}}
I have a ListBox with its ItemSource bound to an ObservableCollection. The ListBox has the following (minimalized) ItemTemplate:
<ListBox ItemsSource="{Binding SelectedDirectory.PluginValues}" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid Height="29" Margin="5" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Width="Auto"
Text="{Binding Name, Mode=TwoWay
, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Grid.Column="1" Width="Auto"
Text="{Binding Value, Mode=TwoWay
, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The binding option UpdateSourceTrigger=PropertyChanged causes the TextBoxes to loose the focus after each keypress to the surrounding ListBox. When I remove the option the focus is not lost, but the value in the TextBox is not immediately saved to the property. So when I enter a value and then raise a command (eg via save Button) the property is not updated. Only when I click somewhere else first and then raise the command the value is updated.
Edit
Simplified ViewModel:
public class ViewModel : INotifyPropertyChanged
{
private FbiDirectory selectedDirectory;
public FbiDirectory SelectedDirectory
{
get
{
return this.selectedDirectory;
}
set
{
this.selectedDirectory = value;
this.OnPropertyChanged("SelectedDirectory");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
FbiDirectory class (has nothing to do with the Federal Bureau of investigation):
public class FbiDirectory : INotifyPropertyChanged
{
private ObservableCollection<PluginValue> pluginValues = new ObservableCollection<PluginValue>();
public ObservableCollection<PluginValue> PluginValues
{
get
{
return this.pluginValues;
}
set
{
this.pluginValues = value;
this.OnPropertyChanged("PluginValues");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
PluginValue class:
public class PluginValue : INotifyPropertyChanged
{
private string name;
private string value;
public string Name
{
get => name;
set
{
name = value;
this.OnPropertyChanged("Name");
}
}
public string Value
{
get => value;
set
{
this.value = value;
this.OnPropertyChanged("Value");
}
}
public PluginValue(string name, string value)
{
this.Name = name;
this.Value = value;
}
public PluginValue()
{
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
A simplified code for your problem may look like this:
public class MyViewModel
{
public ObservableCollection<ItemViewModel> Items { get; set; }
public ICommand SaveCommand { get; }
public MyViewModel()
{
SaveCommand = new RelayCommand(OnSaveCommand);
Items = new ObservableCollection<ItemViewModel>();
Items.Add(new ItemViewModel{Name = "test1", Value = "test1"});
Items.Add(new ItemViewModel{Name = "test2", Value = "test2"});
}
private void OnSaveCommand()
{
var message = Items.Aggregate(new StringBuilder(),
(builder, item) => builder.AppendLine($"{item.Name} {item.Value}"));
message.AppendLine("Will be save");
MessageBox.Show(message.ToString());
}
}
public class ItemViewModel : NotifiableObject
{
private string _value;
private string _name;
public string Name
{
get => _name;
set
{
OnPropertyChanged();
_name = value;
}
}
public string Value
{
get => _value;
set
{
OnPropertyChanged();
_value = value;
}
}
}
public class NotifiableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
With this view:
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<ListBox ItemsSource="{Binding Items}" Grid.Row="0">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid Height="29" Margin="5" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Grid.Column="1" Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Grid.Row="1" Content="Save" Command="{Binding SaveCommand}"></Button>
</Grid>
Not really sure of what's wrong in your code but:
You should use a NotifableObject for the common RaisePropertyChanged behavior
I don't really understand why you use a FbiDirectory instead of directly put the pluginValues into your ViewModel?
Hope it helps.
I am trying to create a conditional textbox usercontrol on which there will be a property that accepts
Condition (true|false, Binding)
FalseValue (true|false, Binding, StaticResource)
TrueValue (true|false, Binding, StaticResource)
The problem is my StaticResource and literal value is working good except for the binding.
<Grid Background="#FFBDBDBD" Margin="0,154,0,266">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="33*"></RowDefinition>
<RowDefinition Height="33*"></RowDefinition>
<RowDefinition Height="33*"></RowDefinition>
</Grid.RowDefinitions>
<userControls:ConditionalTextBox
Grid.Column="0"
Grid.Row="0"
Condition="{Binding Path=IsTrue, Mode=TwoWay}"
FalseValue="{StaticResource FalseValRes}"
TrueValue="{StaticResource TrueValRes}"
HorizontalAlignment="Left" Width="500">
</userControls:ConditionalTextBox>
<userControls:ConditionalTextBox
Grid.Column="0"
Grid.Row="1"
Condition="True"
FalseValue="{Binding FalseValueDefined}"
TrueValue="{Binding TrueValueDefined}"
HorizontalAlignment="Left" Width="500">
</userControls:ConditionalTextBox>
<userControls:ConditionalTextBox
Grid.Column="0"
Grid.Row="2"
Condition="False"
FalseValue="False Value (string)"
TrueValue="True Value (string)"
HorizontalAlignment="Left" Width="500">
</userControls:ConditionalTextBox>
</Grid>
with code behind
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.DataContext = new VMTest
{
IsTrue = true,
FalseValueDefined = "False Value (Binding)",
TrueValueDefined = "True Value (Binding)"
};
}
}
and this VM
public class VMTest : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool isTrue;
public bool IsTrue
{
get { return isTrue; }
set
{
isTrue = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsTrue"));
}
}
private string trueValueDefined;
public string TrueValueDefined
{
get { return trueValueDefined; }
set
{
trueValueDefined = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("TrueValueDefined"));
}
}
public string falseValueDefined;
public string FalseValueDefined
{
get { return falseValueDefined; }
set
{
falseValueDefined = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("FalseValueDefined"));
}
}
}
as the result, StaticResource and literal value reached successfully to UserControl and maybe i missed something on bindings that it wont affect
Result
Any help would be appreciated.
TIA
I would start by looking at the datacontext resolution. Have you tried, just to make sure the datacontext is correct:
<userControls:ConditionalTextBox
x:Name="boundControl"
Grid.Column="0"
Grid.Row="1"
Condition="True"
FalseValue="{Binding FalseValueDefined}"
TrueValue="{Binding TrueValueDefined}"
HorizontalAlignment="Left" Width="500">
</userControls:ConditionalTextBox>
and
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.boundControl.DataContext = new VMTest
{
IsTrue = true,
FalseValueDefined = "False Value (Binding)",
TrueValueDefined = "True Value (Binding)"
};
}
}
It might also be helpful to examine the binding trace information. Try
"{Binding FalseValueDefined, PresentationTraceSources.TraceLevel=High}"
If you run your program and look at the visual studio debug output, you will get some debug rows describing WPF's attempts to resolve the binding.
I have Observable collection with MarketPrices , This observable collection I have bind to an ItemsControl as Below .
1) Now I don't want to show all Items in Observable Collection , want to show only items that user click Add and selected Pair (GBPJPY, USDGBP..) needs to show in Items Control.
2) If user changed item in Comobobox from GBPJPY to USDGBP , then the price( DataTemplate) of GBPJPY need to update USDGBP.
How can I achieve both conditions. Please note that below code doesn't have real-time update but in project I have relatime price update as well, so observable collection updates on price changes.
Code So Far
public class PriceModel : INotifyPropertyChanged
{
private double _askPrice;
private double _offerPrice;
private string _selectedPair;
public PriceModel()
{
Pairs = new ObservableCollection<string> {"GBPUSD", "GBPEUR", "USDGBP", "GBPJPY"};
}
public double AskPrice
{
get { return _askPrice; }
set
{
_askPrice = value;
OnPropertyChanged("AskPrice");
}
}
public double OfferPrice
{
get { return _offerPrice; }
set
{
_offerPrice = value;
OnPropertyChanged("OfferPrice");
}
}
public string SelectedPair
{
get { return _selectedPair; }
set
{
_selectedPair = value;
OnPropertyChanged(SelectedPair);
}
}
public ObservableCollection<string> Pairs { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
MarketPrices = new ObservableCollection<PriceModel>
{
new PriceModel {AskPrice = 1.60345, OfferPrice = 1.60335, SelectedPair = "GBPUSD"},
new PriceModel {AskPrice = 1.71345, OfferPrice = 1.71335, SelectedPair = "GBPEUR"},
new PriceModel {AskPrice = 1.23345, OfferPrice = 1.23335, SelectedPair = "USDGBP"},
new PriceModel {AskPrice = 1.34345, OfferPrice = 1.34335, SelectedPair = "GBPJPY"}
};
}
public ObservableCollection<PriceModel> MarketPrices { get; set; }
}
XAML
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding MarketPrices}">
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="FrameworkElement.Margin" Value="5" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<WrapPanel AllowDrop="True" ClipToBounds="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<ComboBox ItemsSource="{Binding Pairs}" SelectedItem="{Binding SelectedPair}" />
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal">
<TextBlock Margin="2" Text="Ask Price" />
<TextBlock Margin="2" Text="{Binding AskPrice}" />
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<TextBlock Margin="2" Text="Offer Price" />
<TextBlock Margin="2" Text="{Binding OfferPrice}" />
</StackPanel>
</Grid>
</Grid>
</WrapPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
If I understand your question correctly, you want to display a list of pairs in a ComboBox and the details for a Selected pair only but not for all pairs?
If that's the case, there are couple problems with the code.
PriceModel
You do not need a collection of all available pairs in your PriceModel class. Also, You do not need SelectedPair property in this class, may be your intention was to indicate the name of the pair, you could update your PriceModel to:
public class PriceModel : INotifyPropertyChanged
{
private double _askPrice;
private double _offerPrice;
private string _pair;
public PriceModel(string pair)
{
_pair = pair;
}
public string Pair
{
get { return _pair; }
}
public double AskPrice
{
get { return _askPrice; }
set
{
_askPrice = value;
OnPropertyChanged("AskPrice");
}
}
public double OfferPrice
{
get { return _offerPrice; }
set
{
_offerPrice = value;
OnPropertyChanged("OfferPrice");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
MainWindow.xaml.cs
You have a property named MarketPrices to hold the collection of Pairs, but no property to hold the Selected pair. Add a property named SelectedPair of type PriceModel. The Updated code would like this:
public partial class MainWindow : Window, INotifyPropertyChanged
{
private PriceModel _selectedPair;
public MainWindow()
{
InitializeComponent();
DataContext = this;
MarketPrices = new ObservableCollection<PriceModel>
{
new PriceModel("GBPUSD") {AskPrice = 1.60345, OfferPrice = 1.60335, },
new PriceModel("GBPEUR") {AskPrice = 1.71345, OfferPrice = 1.71335, },
new PriceModel("USDGBP") {AskPrice = 1.23345, OfferPrice = 1.23335, },
new PriceModel("GBPJPY") {AskPrice = 1.34345, OfferPrice = 1.34335, }
};
}
public ObservableCollection<PriceModel> MarketPrices { get; set; }
public PriceModel SelectedPair
{
get { return _selectedPair; }
set
{
_selectedPair = value;
OnPropertyChanged("SelectedPair");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
MainWindow.xaml
You could just use ComboBox to display the list of available pairs and update your bindings for TextBoxes to refer SelectedPair.
Update XAML would look like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<ComboBox ItemsSource="{Binding Pairs}" SelectedItem="{Binding SelectedPair}" />
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal">
<TextBlock Margin="2" Text="Ask Price" />
<TextBlock Margin="2" Text="{Binding SelectedPair.AskPrice}" />
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<TextBlock Margin="2" Text="Offer Price" />
<TextBlock Margin="2" Text="{Binding SelectedPair.OfferPrice}" />
</StackPanel>
</Grid>
</Grid>
Sample Output
I am Unable to fetch the property of another classe on the mainwindow.xaml textboxes.In the MainWindow.xaml i am trying to fetch the property value that is defined on the mainwindow.xaml.cs.Here I am successfully fetching the Name Property of ABC class in the first textbox.Details are below:
MainWindow.xaml
<Window x:Class="WpfApplication7.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" Name="UI">
<Grid DataContext="{Binding}">
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical" Grid.Row="0">
<TextBox Text="{Binding Name1}"/>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Row="1">
<TextBox Text="{Binding class1.Name1}"/>
</StackPanel>
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window,INotifyPropertyChanged
{
Class1 c1 = new Class1();
public MainWindow()
{
InitializeComponent();
ABC win = new ABC();
win.Name1 = "Main Window";
c1.Name = "Class 1";
this.DataContext = win;
}
public class ABC
{
public string Name { get; set; }
}
public Class1 class1
{
get
{
return c1;
}
set
{
c1 = value;
INotifyChanged("class1");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void INotifyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this,new PropertyChangedEventArgs(name));
}
}
}
Class1.cs
public class Class1:INotifyPropertyChanged
{
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
NotifyPropertyChanged("Name");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
Class1 it has 1 property called Name so your xaml will have to be <TextBox Text="{Binding class1.Name}"/>, and you seem to be setting your DataContext to a nested class you can't do that, Nested classes are not supported in xaml.
You will have to add ABC as a variable and remove as a nested class
Example:
Xaml:
<Window x:Class="WpfApplication7.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" Name="UI">
<Grid DataContext="{Binding ElementName=UI}">
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<!--You can't bind to a nested class-->
<!--<StackPanel Orientation="Vertical" Grid.Row="0">
<TextBox Text="{Binding Name1}"/>
</StackPanel>-->
<StackPanel Orientation="Vertical" Grid.Row="0">
<TextBox Text="{Binding ABCClass.Name1}"/>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Row="1">
<TextBox Text="{Binding class1.Name}"/>
</StackPanel>
</Grid>
</Window
Code:
public partial class MainWindow : Window, INotifyPropertyChanged
{
private Class1 c1 = new Class1();
private ABC _abcClass = new ABC();
public MainWindow()
{
InitializeComponent();
class1.Name = "Class 1";
_abcClass.Name1 = "ABC Class";
}
public ABC ABCClass
{
get { return _abcClass; }
set { _abcClass = value; INotifyChanged("ABCClass"); }
}
public Class1 class1
{
get { return c1; }
set { c1 = value; INotifyChanged("class1"); }
}
public event PropertyChangedEventHandler PropertyChanged;
public void INotifyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Classes
public class Class1 : NotifyBase
{
private string name;
public string Name
{
get { return name; }
set { name = value; NotifyPropertyChanged("Name"); }
}
}
public class ABC : NotifyBase
{
private string name;
public string Name1
{
get { return name; }
set { name = value; NotifyPropertyChanged("Name1"); }
}
}
public class NotifyBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
Result: