Reputation: 103
I am a newbie in WPF, I have a problem concern DataContext inheritance from the MainWindow to a UserControl, which will be attached as a Tabpage to the MainWindow's Tabcontrol.
My code snippets are as follows:
UserControlModel.cs
public class UserControlModel : INotifyPropertyChanged
{
private string _name;
public string Name
{
get { return _name; }
set
{
if (_name != value)
{
_name = value;
OnPropertyChanged("Name");
}
}
}
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
ViewModelLocator.cs
public class ViewModelLocator
{
private UserControlModel UserControlModel { get; set; }
public ObservableCollection<UserControlModel> Users { get; set; }
public ViewModelLocator()
{
Users = new ObservableCollection<UserControlModel>
{
new UserControlModel { Name = "Albert" },
new UserControlModel { Name = "Brian" }
};
}
}
MainWindow.xaml
<Window.Resources>
<local:ViewModelLocator x:Key="VMLocator" />
</Window.Resources>
<Grid HorizontalAlignment="Left" Height="330" VerticalAlignment="Top" Width="592">
<Grid HorizontalAlignment="Left" Height="45" Margin="0,330,-1,-45" VerticalAlignment="Top" Width="593">
<Button Content="Button" HorizontalAlignment="Left" Margin="490,5,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
</Grid>
<TabControl HorizontalAlignment="Left" Height="330" VerticalAlignment="Top" Width="592" >
<TabItem x:Name="UserControlTabItem" Header="User Control">
<Grid x:Name="UserControlTabpage" Background="#FFE5E5E5">
<local:UserControl VerticalAlignment="Top" DataContext="{Binding Users, Source={StaticResource VMLocator}}" />
</Grid>
</TabItem>
</TabControl>
</Grid>
I create an instance of ViewModelLocator and bind Users instance to the UserControl in MainWindow.xaml.
MainWindow.xaml.cs
public MainWindow()
{
InitializeComponent();
}
UserControl.xaml
<Grid>
<ListBox x:Name="lbUsers" DisplayMemberPath="???" HorizontalAlignment="Left" Height="250" Margin="30,27,0,0" VerticalAlignment="Top" Width="378"/>
</Grid>
UserControl.xaml.cs
private ObservableCollection<UserControlModel> _users;
public UserControl()
{
InitializeComponent();
_users = ???;// How to reference the Users instance created in MainWindow ???
lbUsers.ItemsSource = _users;
}
Actually, I want to show the Name
property of UserControlModel
in the ListBox
. If I am right, UserControl
instance is
inherited with a Users
instance as the DataContext
from MainWindow
. How can I reference the Users
instance in the code-behind of UserControl.xaml.cs
?
I have checked that DataContext
in UserControl
constructor is null
! How come? What is the
correct way/place to test the DataContext
in the code-behind?
Also, how to set DisplayMemberPath
attribute of the ListBox
in UserControl.xaml
. Many thanks.
Upvotes: 1
Views: 1009
Reputation: 169150
You need to bind the ItemsSource
property of the ListBox
to the source collection. Since the DataContext
of the UserControl
is a ObservableCollection<UserControlModel>
, you can bind to it directly:
<ListBox x:Name="lbUsers" ItemsSource="{Binding}" DisplayMemberPath="Name" ... />
Also make sure that you don't explicitly set the DataContext
of the UserControl
anywhere else in your code.
Although you should be able to reference the DataContext once the UserControl
has been loaded:
public UserControl()
{
InitializeComponent();
this.Loaded += (s, e) =>
{
_users = DataContext as ObservableCollection<UserControlModel>;
};
}
...there is no need to set the ItemsSource
property of the ListBox
in the code-behind. You should do this by creating a binding in the XAML.
Upvotes: 0
Reputation: 66
I think you can set or inherit DataContext in XAML of user control like this
UserControl.xaml
<dialogs:Usercontrol DataContext="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext}" />
Upvotes: 1