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>
Related
What is the best way to bind Tag Attribute of ChildButton in TreeView(in the code Tag="{Binding ParentData}" to ParentData property of class TreeParent?
<TreeView>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:TreeParent}" ItemsSource="{Binding Members}">
<Button x:Name="ParentButton" Text="{Binding ParentName}">
</Button>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:TreeChild}" ItemsSource="{Binding Members}">
<Button x:Name="ChildButton" Text="{Binding ChildName}" Tag="{Binding ParentData}">
</Button>
</DataTemplate>
</TreeView.Resources>
</TreeView>
And the .cs code behind xaml file looks like this:
public class TreeParent
{
public string ParentName { get; set; }
public SomeDataClass ParentData { get; set; }
public ObservableCollection<TreeChild> Members { get; set; }
}
public class TreeChild
{
public string ChildName { get; set; }
}
Try this:
<Button x:Name="ChildButton" ...
Tag="{Binding DataContext.ParentData,
RelativeSource={RelativeSource AncestorType=TreeViewItem, AncestorLevel=2}}" />
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>
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 !
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>
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>