ItemControl with 2 sources - c#

I have the following Classes:
public class agentes
{
[PrimaryKey]
public string id { get; set; }
public string idContinente { get; set; }
public string idCountry { get; set; }
public string title { get; set; }
public string desc { get; set; }
}
and
public class country
{
[PrimaryKey]
public string id { get; set; }
public string idContinent { get; set; }
public string title { get; set; }
}
i also have 2 other classes, and have a List of objects of each of those types , country and agents.
my List is filled with the results from a Database query to a sqlite database that looks something like this:
public List<agentes> GetAllAgents()
{
List<agentes> AllAgents = new List<agentes>();
using (var db = new SQLite.SQLiteConnection(app.DBPath))
{
var query = db.Table<agentes>().OrderBy(c => c.idCountry);
foreach (var _Agent in query)
{
var Agente = new agentes()
{
desc = _Agent.desc,
id = _Agent.id,
idContinente = _Agent.idContinente,
idCountry = _Agent.idCountry,
title = _Agent.title,
};
AllAgents.Add(Agente);
}
}
return AllAgents;
}
Now, what i intend to do , is a list of agents organized by country so it looks something like
i started with something like this but clearly it inst whats needed
<ScrollViewer Margin="30,30,0,30" Height="444">
<ItemsControl Name="ListCountries">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding title}" Foreground="Red" />
<ItemsControl Name="AgentsByCountry" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding desc}" Foreground="Black" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
anyone got any suggestions how i can do this?

You can use LINQ to group by title which will create IGrouping for each country where Key will be your country:
ListCountries.ItemsSource = GetAllAgents().GroupBy(a => a.title);
and then change binding for inner TextBlock and ItemsControl like so
<ScrollViewer Margin="30,30,0,30" Height="444">
<ItemsControl Name="ListCountries">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Key}" Foreground="Red"/>
<ItemsControl ItemsSource="{Binding}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding desc}" Foreground="Black" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>

Related

WPF Hierarchial Data Template differrent properties in classes

How to make tree where leaves would be different properties of the classes?
I want to get something like this
AMachine
-Wheels
Bmachine
-Years
Code.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new TestViewModel();
}
}
public class TestViewModel
{
public ObservableCollection<IBase> Items { get; set; }
public TestViewModel()
{
Items = new ObservableCollection<IBase>();
Items.Add(new AMachine { Wheels = "3", Name = "AMachine" });
Items.Add(new BMachine { Years = "2", Name = "BMachine" });
}
}
public interface IBase
{
}
public class AMachine : IBase
{
public string Name { get; set; }
public string Wheels { get; set; }
}
public class BMachine : IBase
{
public string Name { get; set; }
public string Years { get; set; }
}
Xaml.cs
<Grid>
<TreeView Height="300" Width="300" ItemsSource="{Binding Items}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type self:IBase}" ItemsSource="{Binding Items}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
You don't need hierarchical data template here, the logical would be to use normal data templates and ListBox (with expanders as nodes?):
<ListBox ItemsSource="{Binding Items}">
<ListBox.Resources>
<DataTemplate DataType="{x:Type local:AMachine}">
<Expander Header="{Binding Name}">
<TextBlock Text="{Binding Wheels}" />
</Expander>
</DataTemplate>
<DataTemplate DataType="{x:Type local:BMachine}">
<Expander Header="{Binding Name}">
<TextBlock Text="{Binding Years}" />
</Expander>
</DataTemplate>
</ListBox.Resources>
</ListBox>

How to organize ItemSource for such DataGrid

I'm Using MVVM and can't figure out how to organize ItemSource class for such DataGrid.
DataGrid XAMl code:
<DataGrid CanUserAddRows="True"
ItemsSource="{Binding TestCollection}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="First Column">
<DataGridTemplateColumn.CellEditingTemplate >
<DataTemplate >
<ContentControl>
<StackPanel>
<TextBox Text="{Binding First}"/>
<TextBox Text="{Binding Second}"/>
</StackPanel>
</ContentControl>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Second Column">
<DataGridTemplateColumn.CellEditingTemplate >
<DataTemplate >
<ContentControl>
<StackPanel>
<TextBox Text="{Binding Third}"/>
<TextBox Text="{Binding Fourth}"/>
</StackPanel>
</ContentControl>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
I have this idea, but it doesn't work.
public class ComplexTable
{
public ComplexTable()
{
FirstProperty = new FirstClass();
SecondProperty = new Second();
}
public class FirstClass
{
public FirstClass()
{
First = "FirstString";
Second = "SecondString";
}
public string First { get; set; }
public string Second { get; set; }
}
public class Second
{
public Second()
{
Third = "ThirdString";
Fourth = "FourthString";
}
public string Third { get; set; }
public string Fourth { get; set; }
}
public FirstClass FirstProperty { get; set; }
public Second SecondProperty { get; set; }
}
public ObservableCollection<ComplexTable> _testCollection = new ObservableCollection<ComplexTable>();
private ObservableCollection<ComplexTable> TestCollection
{
get { return _testCollection; }
set
{
_testCollection = value;
RaisePropertyChanged("TestCollection");
}
}
As i understand each property in class for ItemSource responsible for column in DataGrid, and if cell contains several controls etc. property Type should consist property for each control as well. Cant figure out where am i wrong.
http://www.codeproject.com/Articles/683429/Guide-to-WPF-DataGrid-formatting-using-bindings
You can understand with this link.
<StackPanel>
<TextBox Text="{Binding SelectedItem.Name, ElementName=myDataGrid}"/>
<DataGrid x:Name="myDataGrid" />
</StackPanel>

WPF List inside List Binding

I am using nested ListBox for databinding,
This is my ListBox
<ListBox x:Name="lst1" ItemsSource="{Binding ListDS}" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Margin="10">
<TextBlock Text="{Binding Name}"/>
<ListBox Height="300" Width="200" ItemsSource="{Binding userFiles }" Margin="0,10" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,10,0,0">
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Print" Width="75" HorizontalAlignment="Right" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Margin="0,0,0,0" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
These are my entities
public class UsersInfo
{
public long Id { get; set; }
public string Name { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateUploaded { get; set; }
public List<UsersFiles> userFiles { get; set; }
}
public class UsersFiles
{
public long Id { get; set; }
public string Name { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateDownloaded { get; set; }
}
and in my ViewModel, I have this
public List<UsersInfo> ListDS{ get; set; }
I am initializing it in my ViewModel's constructor and this is how I am populating the data
UsersInfo entity = new UsersInfo();
entity.MediaFiles = new List<UsersFiles>();
UsersFiles mFiles = new UsersFiles();
mFiles.Name = "abc";
mFiles.Id = 1
entity.Name = "User name";
entity.MediaFiles.Add(mFiles);
ListDS.Add(entity);
The problem is, ListBox is appearing blank, nothing is showing on it,even Print button.
When I added ListBoxItem in it,its showing perfectly.
Where I am doing wrong in databinding?
You have to implement INotifyPropertyChanged interface. The interface will notify the view when the property changes.
But you want your view to be notified if there is any new item in the collection so it's better to use a collection that will do that for you. Use ObservableCollection<UserInfo> to expose your ListDS.
public ObservableCollection<UserInfo> ListDS
{
get { return listDS; }
set
{
listDS = value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("ListDS");
}
}
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
assuming your view-model code is correct you only need to change this:
<ListBox Height="300" Width="200" ItemsSource="{Binding ListDS2}" Margin="0,10" >
to this:
<ListBox Height="300" Width="200" ItemsSource="{Binding userFiles}" Margin="0,10" >
and it will work. note the incorrect binding value !

Binding nested JSON to listbox in XAML

This is my modal,
public class main
{
public List<categories> categorieslist { get; set; }
}
public class categories
{
public int categoryId { get; set; }
public string categoryName { get; set; }
public List<pdf> pdfdocs { get; set; }
public List<video> videoFiles { get; set; }
}
public class pdf
{
public string URL { get; set; }
public string language { get; set; }
public string createdDate { get; set; }
public bool isFavorite { get; set; }
public bool isRead { get; set; }
}
Im using JSON.NET to deserialize
main mainobj = JsonConvert.DeserializeObject<main>(App.hello);
I need to display list of PDF's for a selected category,
Im using LINQ to filter that particular category, I am unable to bind the PDF list..
pdf.ItemsSource = App.mainobj.categorieslist.Where(i => i.categoryId.Equals(s));
<ListBox x:Name="pdf" Margin="0,0,0,363" ItemsSource="{Binding}" Foreground="White">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding pdf.URL}" Foreground="White"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox ItemsSource="{Binding categorieslist}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding categoryId }" FontSize="20" />
<ItemsControl ItemsSource="{Binding pdf}" Margin="0 20 0 0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Blue" BorderThickness="2">
<TextBlock Text="{Binding URL }" FontSize="20" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl ItemsSource="{Binding videoFiles}" Margin="0 20 0 0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Red" BorderThickness="2">
<TextBlock Text="{Binding URL}" FontSize="20" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>

Get Object properties of selected list item

I have a listbox that has a listsource that is a list of 'results' objects. The results class looks like this:
public class Result
{
public string GUID { get; set; }
public string __invalid_name__I { get; set; }
public string FN { get; set; }
public string DOB { get; set; }
public string SEX { get; set; }
public string SN { get; set; }
public string __invalid_name__U { get; set; }
public string TYPE { get; set; }
//Gender icon path associated with result
public string SexIcon { get; set; }
}
And this is what my listbox looks like in the xaml code:
<ListBox
Height="517"
HorizontalAlignment="Left"
Margin="12,84,0,0"
Name="searchList"
VerticalAlignment="Top"
Width="438"
SelectionChanged="SearchList_SelectedEvent">
<!-- What each listbox item will look like -->
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Path=Sex, Converter={StaticResource SexToSourceConverter}}" Visibility="Visible" />
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Name="FirstName" Text="{Binding FN}" FontSize="28" Margin="0,0,10,0"/>
<TextBlock Name="LastName" Text="{Binding SN}" FontSize="28" />
</StackPanel>
<TextBlock Text="{Binding DOB}" FontSize="24" />
<!-- Line Stroke="#FF04863C" StrokeThickness="3" X1="100" Y1="100" X2="300" Y2="100" / -->
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
So my question is, (and what I'm really struggling with) is how does one for instance get the value of the GUID property of the selected Item (which is basically a results object)?
(searchList.SelectedItem as Result).GUID

Categories