Bind nested listview from ViewModel in WPF - wpf

I am beginner in WPF. I am trying bind nested listview from ViewModel.
I have two listview parent and child respectively. In my parent listview datatemplate want bind child listview it's something
like nested gridview in asp.net. Could any one there please help me to sort out this problem.
Data Display like:
StudentID Name
S101 Azad
Math 3
C# 3
Here StudentID,Name parent listview content and subjects are child listview content which is filter by StudentID.
Thanks,
Az#d

<Grid>
<ListView ItemsSource="{Binding Students}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="2"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" Grid.Column="0"/>
<TextBlock Text="{Binding RollNo}" Grid.Column="2"/>
<ListView ItemsSource="{Binding SubjectAndMarks}" Grid.Row="2" Grid.ColumnSpan="2" Grid.Column="0" BorderThickness="0">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Subject}" Grid.Column="0"/>
<TextBlock Text="{Binding Marks}" Grid.Column="2"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
public class SubjectAndMarks
{
public string Subject { get; set; }
public double Marks { get; set; }
}
public class Student
{
public string Name { get; set; }
public int RollNo { get; set; }
public ObservableCollection<SubjectAndMarks> SubjectAndMarks { get; set; }
}
public class ViewModel //ViewModel
{
public ObservableCollection<Student> Students { get; set; }
public ViewModel()
{
Students = new ObservableCollection<Student>();
Students.Add(new Student()
{
Name = "Harish",
RollNo = 1,
SubjectAndMarks = new ObservableCollection<SubjectAndMarks>()
{new SubjectAndMarks(){Subject="Maths",Marks=100},new SubjectAndMarks(){Subject="Hindi",Marks=100},
new SubjectAndMarks(){Subject="Science",Marks=100}}
});
Students.Add(new Student()
{
Name = "Pankaj",
RollNo = 2,
SubjectAndMarks = new ObservableCollection<SubjectAndMarks>()
{new SubjectAndMarks(){Subject="Maths",Marks=100},new SubjectAndMarks(){Subject="Hindi",Marks=40},
new SubjectAndMarks(){Subject="Science",Marks=30}}
});
Students.Add(new Student()
{
Name = "Deepak",
RollNo = 3,
SubjectAndMarks = new ObservableCollection<SubjectAndMarks>()
{new SubjectAndMarks(){Subject="Maths",Marks=90},new SubjectAndMarks(){Subject="Hindi",Marks=50},
new SubjectAndMarks(){Subject="Science",Marks=60}}
});
}
}
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
I hope that will help.

Related

How to get datacontext of an event emitting item control?

I have a bunch of buttons being render inside an items control. I want to get access to the data context of the clicked button. How can I achieve that?
Model:
public class RunYear
{
public RunYear(int year)
{
Year = year;
Months = new Month[3];
}
public int Year { get; set; }
public Month[] Months { get; set; }
}
public class Month
{
public int ColumnIndex { get; set; }
public string MonthName { get; set; }
// some other props
}
Code behind:
public partial class MainWindow : Window
{
private ObservableCollection<RunYear> _years = new ObservableCollection<RunYear>();
public ObservableCollection<RunYear> Years { get{return _years; } }
public MainWindow()
{
DataContext = this;
InitializeComponent();
GenerateData();
}
private void GenerateData()
{
for (int i = 2010; i < 2015; i++)
{
var runYear = new RunYear(i);
runYear.Months[0] = new Month() { ColumnIndex = 0, MonthName = $"Jan {i}" };
runYear.Months[1] = new Month() { ColumnIndex = 1, MonthName = $"Feb {i}" };
runYear.Months[2] = new Month() { ColumnIndex = 2, MonthName = $"Mar {i}" };
Years.Add(runYear);
}
}
public void OnClick(object sender, RoutedEventArgs args)
{
// how do I get the databound item?
var cp = sender as ContentPresenter; //doesn't work
var vm = cp?.Content as Month;
}
}
XAML:
<Grid>
<ItemsControl Name="icYears" ItemsSource="{Binding Years}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="75"/>
</Grid.RowDefinitions>
<DockPanel Grid.Column="0" Grid.Row="0" >
<TextBox IsReadOnly="True" TextAlignment="Center" Text="{Binding Year}" />
</DockPanel>
<ItemsControl Grid.Column="1" Name="icMonths" ItemsSource="{Binding Months}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="75"></RowDefinition>
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Column" Value="{Binding ColumnIndex}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Click="OnClick" Content="{Binding MonthName}" Padding="2" Margin="2"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
Do you mean like this?
private void Button_Click(object sender, RoutedEventArgs e)
{
var vm = (sender as FrameworkElement).DataContext;

WPF: Can only bind to List if DataContext set directly

I'm learning WPF. Thanks in advance for the help.
I have an object, Directory, that acts as a container for a List of Person objects. I can't figure out why I can't bind my ListBox to the list of Person unless I set the DataContext directly. In other words, I can't use dot notation to access the list as a sub-property of the directory.
Observe the the last line of the C# sharp code below: I set the DataContext to this.directory.People and it works great.
But if I set the DataContext simply to this (to refer to the whole Window) and then try to use dot notation to set my binding like <ListBox ItemsSource="{Binding Path=directory.People}" /> my ListBox is blank.
XAML listed below. Observe the last line of the XAML.
CodeBehind:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class Directory
{
public List<Person> People = new List<Person>();
public Directory()
{
this.People.Add(new Person() { Name = "Joseph", Age = 34 });
this.People.Add(new Person() { Name = "Teresa", Age = 29});
this.People.Add(new Person() { Name = "Kulwant", Age = 66 });
this.People.Add(new Person() { Name = "Hyunh", Age = 61});
this.People.Add(new Person() { Name = "Marcio", Age = 65 });
}
}
public partial class MainWindow : Window
{
public Directory directory { get; } = new Directory();
public MainWindow()
{
InitializeComponent();
this.DataContext = this.directory.People;
}
}
XAML:
<Window x:Class="WtfDataTrigger.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:t="clr-namespace:System.Threading;assembly=mscorlib"
xmlns:local="clr-namespace:LearningWPF"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate DataType="{x:Type local:Person}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Name="NameLabel" Margin="2" Content="Name" Grid.Column="0" Grid.Row="0" VerticalAlignment="Center" FontWeight="Bold"/>
<TextBlock Name="NameText" Margin="2" Text="{Binding Path=Name}" Grid.Column="1" Grid.Row="0" VerticalAlignment="Center" />
<Label Name="AgeLabel" Margin="2" Content="Age" Grid.Column="0" Grid.Row="1" VerticalAlignment="Center" FontWeight="Bold" />
<TextBlock Name="AgeText" Margin="2" Text="{Binding Path=Age}" Grid.Column="1" Grid.Row="1" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ListBox ItemsSource="{Binding}" />
</StackPanel>
</Window>
WPF data binding works with public properties only. While directory is a public property (but should be named Directory), People is a public field.
Change
public List<Person> People = new List<Person>();
to
public List<Person> People { get; } = new List<Person>();

Binding does not work for TemplateSelector

I have one part of the view is dynamic based on a TemplateSelector. However, the binding does not work for the controls in the DataTemplate.(The controls do show on screen, just the conetent/texts are empty). I suspect it's a DataContext issue, but couldn't figure out after a lot of searching on line. Here is my XAML:
<Grid>
<Grid.DataContext>
<local:MyViewModel/>
</Grid.DataContext>
<Grid.Resources>
<DataTemplate x:Key="T1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Grid.Row="0"
Text="Music"
Style="{StaticResource ResourceKey=textBlockStyle}" />
<TextBox Grid.Column="1"
Grid.Row="0"
Style="{StaticResource ResourceKey=textBoxStyle}"
Text="{Binding Path=MusicName}" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="T2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Grid.Row="0"
Text="Currency"
Style="{StaticResource ResourceKey=textBlockStyle}" />
<ComboBox Grid.Column="1"
Grid.Row="0"
Style="{StaticResource ResourceKey=comboBoxStyle}"
ItemsSource="{Binding Path=Currency_List}"
SelectedItem="{Binding Path=Currency}" />
</Grid>
</DataTemplate>
<local:ProductTypeTemplateSelector T1="{StaticResource ResourceKey=T1}"
T2="{StaticResource ResourceKey=T2}"
x:Key="myTemplateSelector" />
<Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="*" />
<RowDefinition Height="40"/>
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<!-- This biding works -->
<TextBlock Grid.Row="0"
Text="{Binding Path=MusicName}"/>
<!-- This biding does not work -->
<ContentControl Grid.Row="1"
Name="ccc"
Content="{Binding Path=Product_Type}"
ContentTemplateSelector="{StaticResource myTemplateSelector}">
</ContentControl>
</Grid>
This is my View Model (Technically, it is View Model and Model mixed together. I am not really implementing a full MVVM pattern)
public class MyViewModel: INotifyPropertyChanged
{
public MyViewModel()
{
SetLists();
}
protected void SetLists()
{
SetList_Product_Type();
SetList_Currency();
}
protected void SearchAndPopulate()
{
string query = string.Format("select * from dbo.vehicle_attributes where ticker like '%{0}%'", Search_Text);
DataView dv = DAL.ExecuteQuery(query);
if (dv.Count > 0)
{
DataRowView dvr = dv[0];
Vehicle_Id = int.Parse(dvr["vehicle_id"].ToString());
Product_Type = dvr["product_type_name"].ToString();
Vehicle_Name = dvr["vehicle_name"].ToString();
Is_Onshore = dvr["domicile_name"].ToString() == "Onshore";
Currency = dvr["currency"].ToString();
CUSIP = dvr["CUSIP"].ToString();
ISIN = dvr["isin"].ToString();
Ticker = dvr["ticker"].ToString();
Valoren = dvr["valoren"].ToString();
PC_Class = PC_Class_List.Find(x => x.Class_Name == dvr["class_name"].ToString());
Implementation_Type = Implementation_Type_List.Find ( x => x.Implementation_Type_Name == dvr["implementation_type_name"].ToString());
Price_Frequency = Price_Frequency_List.Find( x => x.Price_Frequency_Name == dvr["price_freq_name"].ToString());
Status = Status_List.Find( x => x.Status_Name == dvr["status_name"].ToString());
if (!string.IsNullOrEmpty(dvr["last_status_update"].ToString()))
{
Status_Date = DateTime.Parse(dvr["last_status_update"].ToString());
}
else
{
Status_Date = DateTime.MinValue;
}
switch (Product_Type)
{
case "Mutual Fund":
query = string.Format("select lf.dividend_currency, i.ticker from dbo.liquid_funds lf " +
"left join dbo.vehicles i on i.vehicle_id = lf.index_id " +
"where lf.vehicle_id ='{0}'",Vehicle_Id);
DataView dv_mutual_fund = DAL.ExecuteQuery(query);
if(dv_mutual_fund.Count > 0)
{
DataRowView dvr_mutual_fund = dv_mutual_fund[0];
Dividend_Currency = dvr_mutual_fund["dividend_currency"].ToString();
Benchmark_Ticker = dvr_mutual_fund["ticker"].ToString();
}
break;
default:
break;
}
}
}
public ICommand SearchVehicleCommand
{
get
{
return new Command.DelegateCommand(SearchAndPopulate);
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
//ProductType
protected List<string> _product_Type_List = new List<string>();
public List<string> Product_Type_List
{
get
{
return _product_Type_List;
}
set
{
_product_Type_List = value;
OnPropertyChanged("Product_Type_List");
}
}
protected void SetList_Product_Type()
{
string query = "SELECT * FROM dbo.product_types WHERE is_enabled = 1";
DataView dv = DAL.ExecuteQuery(query);
List<string> l = new List<string>();
for (int i = 0; i < dv.Count; i++)
{
l.Add(dv[i]["product_type_name"].ToString());
}
Product_Type_List = l;
}
protected string _product_type;
public string Product_Type
{
get
{
return _product_type;
}
set
{
_product_type = value;
OnPropertyChanged("Product_Type");
SetList_Implementation_Type();
}
}
//Currency
protected List<string> _currency_List = new List<string>();
public List<string> Currency_List
{
get
{
return _currency_List;
}
set
{
_currency_List = value;
OnPropertyChanged("Currency_List");
}
}
protected void SetList_Currency()
{
string query = "SELECT currency FROM dbo.currencies";
DataView dv = DAL.ExecuteQuery(query);
List<string> l = new List<string>();
for (int i = 0; i < dv.Count; i++)
{
l.Add(dv[i]["currency"].ToString());
}
Currency_List = l;
}
protected string _currency;
public string Currency
{
get
{
return _currency;
}
set
{
_currency = value;
OnPropertyChanged("Currency");
}
}
// Music Name
protected string _musicName;
public string MusicName
{
get
{
return _musicName;
}
set
{
_musicName = value;
OnPropertyChanged("MusicName");
}
}
}
This is the class interface (sorry for the formatting above, but somehow I can't get it right):
And this is my DelegateCommand class:
public class DelegateCommand : ICommand
{
private readonly Action _action;
public DelegateCommand(Action action)
{
_action = action;
}
public void Execute(object parameter)
{
_action();
}
public bool CanExecute(object parameter)
{
return true;
}
}
This is the DataTemplateSelector:
public class MyTemplateSelector : DataTemplateSelector
{
public DataTemplate T1 { get; set; }
public DataTemplate T2 { get; set; }
public override DataTemplate SelectTemplate(object item,
DependencyObject container)
{
string product_type = (string)item;
if (product_type == "Type1")
return T1;
else
return T2;
}
}
The DataContext of a DataTemplate is set to the object that it is bound to. So in your case the DataContext for your Templates are Product_Type and you are expecting it to be MyViewModel.
There is a workaround for what you need. It uses a RelativeSource binding and FindAncester to access the DataContext of the Parent object.
Your DataTemplate bindings should look like this:
XAML
<DataTemplate x:Key="T1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Grid.Row="0"
Text="Music"
Style="{StaticResource ResourceKey=textBlockStyle}" />
<TextBox Grid.Column="1"
Grid.Row="0"
Style="{StaticResource ResourceKey=textBoxStyle}"
Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentControl}}, Path=DataContext.MusicName}" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="T2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Grid.Row="0"
Text="Currency"
Style="{StaticResource ResourceKey=textBlockStyle}" />
<ComboBox Grid.Column="1"
Grid.Row="0"
Style="{StaticResource ResourceKey=comboBoxStyle}"
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentControl}}, Path=DataContext.Currency_List}"
SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentControl}}, Path=DataContext.Currency}" />
</Grid>
</DataTemplate>
From MSDN
Find Ancestor - Refers to the ancestor in the parent chain of the data-bound element. You can use this to bind to an ancestor of a specific type or its subclasses.
The AncestorType attribute goes up the visual tree and finds the first Ancestor of the given type, in this case it's looking for ContentControl the path to the required property can then be set relative to this.
Update
Think of a template as a guide on how to display an object. The DataContext of the DataTemplate is going to be whatever object it is asked it to display.
In this case the ContentControl is told to display Product_Type and, depending on the value of Product_Type, to use a particular Template. Product_Type is given to the DataTemplate and becomes the DataContext.
WPFTutorials has some good examples.

WPF ListBox: Binding to an ObservableCollection

I'm binding my ListBox to an ObservableCollection at runtime. Upon clicking a button, one of the items in my collection gets modified, but the corresponding ListBox item doesn't update itself accordingly. I have gone thru several similar SO articles and other help material and it seems like I'm doing everything they've asked for, but no luck. Everything seems to load and bind correctly, but when I change "IsLoading" property of an item in my collection, the Visibility of the Grid (see DataTemplate below) which is bound to IsLoading property doesn't change.
Following is my ListBox XAML:
<ListBox Name="lstItems">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Name="ListBoxGrid">
<Grid.RowDefinitions>
<RowDefinition Height="120"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="0" IsChecked="{Binding IsSelected}" />
<Image Grid.Column="1" Width="50" Stretch="Uniform" Source="{Binding Image}" />
<TextBlock Grid.Column="2" Text="{Binding Path=ImageFilePath}" />
<Grid Grid.Column="3" Visibility="{Binding IsLoading, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, Mode=TwoWay, BindsDirectlyToSource=True, Converter={StaticResource BooleanToVisibilityConverter1}}">
<my:LoadingAnimation x:Name="SendAnimation" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And here's my BO:
public class Order : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public bool IsSelected { get; set; }
public string ImageFilePath { get; set; }
public ImageSource Image { get; set; }
private bool mIsSending = false;
public bool IsSending
{
get { return mIsSending; }
set
{
mIsSending = value;
if (PropertyChanged != null)
PropertyChanged(null, new PropertyChangedEventArgs("IsSending"));
}
}
}
And this is how I create the collection and bind it:
ObservableCollection<Order> mOrders = new ObservableCollection<Order>();
public MainWindow()
{
InitializeComponent();
lstItems.ItemsSource = mOrders;
}
Nevermind. Sometimes it is that you spend hours digging the problem, finally get frustrated, post it on SO, and the next 2 minutes you figure it out yourself. For any future reader, the only problem was that I was sending null in PropertyChanged event. As soon as I changed that to this, things started working like a charm.

Unable to bind to a collection of my ViewModel

All - Trying to do 2 things: I have a simple app and am trying to bind my Viewmodel collection to my view. Have 2 approaches in mind but am getting stuck on both of them:
Approach 1: Using Grid as a container to bind the textblock property.
Approach 2: Binding an attribute of the object directly to a textblock on my view (not using grid as a container and its Datacontext property)
Rule_Model_1.cs
public class Rule_Model_1
{
public string topMessage { get; set; }
public List<string> recipients { get; set; }
public string bottomMessage { get; set; }
public string hypLink { get; set; }
public OCCBlock blockType { get; set; }
public enum OCCBlock
{
HardBlock,
SoftBlock,
ModifyAndSend
}
}
Rule_VM_1.cs
class Rule_VM_1
{
#region Properties
public List<Rule_Model_1> rule { get; set; }
#endregion
#region Constructor
public Rule_VM_1()
{
#region Initializing a Rule
rule = new List<Rule_Model_1>();
rule.Add(new Rule_Model_1()
{
topMessage = "Lorem ipsum dolor sit amet.",
recipients = new List<string> {"pr#hotmail.com", "pra#gmail.com"},
bottomMessage = "Lorem ipsum dolor sit amet",
hypLink = "http://www.abc.com",
blockType = Rule_Model_1.OCCBlock.HardBlock
});
#endregion
}
#endregion
}
Rule_UI.xaml.cs
public partial class Rule_UI_1 : UserControl
{
Rule_VM_1 rulevm1;
public Rule_UI_1()
{
InitializeComponent();
rulevm1 = new Rule_VM_1();
DataContext = rulevm1;
}
}
Rule_UI.xaml
<UserControl x:Class="OCC_WPF_POC.Rule_UI_1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d">
<GroupBox Header="Rule Details">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Grid.Column="1" DataContext="{Binding rule}">
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="200"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding topmessage}" />
</Grid>
</Grid>
</GroupBox>
The view still shows nothing. Also as mentioned above - how do i have both the approaches working? Any code samples is greatly appreciated
Image Attached
The problem is that you need a list view to bind to a collection property (rule). This should work:
<ListBox Grid.Column="1" ItemsSource="{Binding rule}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding topmessage}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
To bind to the grid, you can set the DataContext using an indexer []:
<Grid Grid.Column="1" DataContext="{Binding rule[0]}">
<TextBlock Grid.Row="0" Text="{Binding topmessage}" />
</Grid>
And without the Grid:
<TextBlock Text="{Binding rule[0].topmessage}" />

Resources