WPF How to use GridView to display a matrix - c#

I am new to WPF programming and I am trying to convert my python program into a UWP app just for practice. The app can dynamically creates new text entries and labels to allow users to input the entries of matrices.
I am currently stuck in how to create a grid to put those text entries and labels. I thought a right choice would be using gridView but the examples that I have seen don't seem to help. Any ideas on how to implement that?
This is my current try:
<GridView x:Name="gridView" Margin="0,150,0,0">
<GridView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
I am also trying to access the Columns attribute of the gridView (System.Windows.Controls) but it seems I am using the wrong gridView (Windows.UI.Xaml.Controls). But VS can't find the correct gridView for me as it doesn't exist. I am very confused with GridView. Can anyone provide some pointers?

ok, so I think your question is : WPF - How to bind a GridView to a Matrix or How to display a Matrix in WPF, if I understood good what you want, this link seems a good solution to your problem on how to bind your Matrix to DataGrid.
For that you need to :
create two ObservableCollection< int >(or ObservableCollection< string > lists in your ViewModel
(For example ListRows and ListColumns)
When you edit your textboxes, you will update ListRows or ListColumns by updating the corresponding ObservableCollection
So using binding, the GridView will automaically update.
But before starting with it, I you need some notions with Binding, ViewModel, ObservableCollection and Converters

Related

Grouping and displaying items of different types in a collection view - Xamarin Forms

I am trying to get a journal type gui, where entries are ordered by their date.
I want to fetch my journal entries from the datbase and group the ones that were added on the same day and separete these groups with a label.
Kind of like the facebook messenger chat history.
This is what I was thinking about:
<ScrollView>
<CollectionView ItemsSource="{Binding JournalEntries}" SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate>
<Label>Date</Label>
<CollectionView ItemsSource="{Binding}">
</CollectionView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ScrollView>
The problem is that 'JournalEntry' object can be of many types.
For example 'Photo' derives from 'JournalEntry'. So if a 'Photo' object is in the 'JournalEntries' collection I want the image to be displayed and not the 'ToString()' text.
What would be he best way to group the JournalEntries into different days, so I can display an label over the group?
How can I decide in runtime wether an object should be displayed as an image or as text?
Any help would be appreciated.
Here are answers:-
You can use JournalEntries.GroupBy(x=> x.date).ToDictionary(). For this you will have to use System.Ling. This will return you a Dictionary, whose Key will be the Date and all the entries in a form of List in the Value. This will be easier for you to use.
You can use a DataTemplateSelector or Converter for choosing an option at runtime. With a DataTemplateSelector you will have to make two DataTemplates one for each Image and Text. For Converter you will have to toggle the visibility on the basis of the data which comes from the Server/Database.
Let me know for further queries. I can help you out for sure!
After some research and some testing I have found a suitable solution for me. Nikhil's answer is correct, but I would say incomplete, specially as it pertains to the DataTemplateSelector part.
First I created a class called EntryGroup which derives from List<Entry>.
After this I created a Property for binding in my ViewModel called Entries which was an IEnumerable of type EntryGroup.
This process is outlined here.
I created a GroupHeaderTemplate to display the dates.
In my ViewModel I get the entries from my repository and use the .GroupBy(it => it.Timestamp.Date) Linq method. This returns an IGrouping<DateTime, Entry>.
Since it already extends IEnumerable, half of the job is done.
I wrote them to the Entries IEnumerable using a foreach loop.
Then I create a class deriving from DataTemplateSelector and created an ImageTemplate and a TextTemplate as outlined here

How can I instantiate complex group of controls and acces to their values? (wpf with visual studio)

I am trying to implement a list of programmatically instanced group of controls such as this one:
Example of my group
.
<Grid>
<TextBlock x:Name="TextBox_Data"/>
<TextBlock x:Name="TextBox_Time"/>
<TextBox x:Name="TextBlock_ID"/>
<ComboBox x:Name="ComboBox_Type"/>
<Button x:Name="Button_Data"/>
<Grid/>
It contains 2 TextBox, 1 TextBlock and 1 ComboBox and 1 button ( detail is pretty irrelevant tough) inside a Grid.
I would like to duplicate the Grid Parent to fill a list, and access to every values of the duplicated controls but I can not figure out how to do this.
I had in mind something equivalent to Android Studio java/xml combo but I couldn't find anything on this topic around here.
Any lead is more than welcome.
Thank you in advance for your time :)
Create a separate UserControl that contains your group of controls.
Do something similar to this:
WPF creating grid from XAML in code-behind
But, instead of code-behind, you can reference your new UserControl in a XAML.

How to use a RowDetails Template with the Telerik WPF TreeListView

I'm using the Telerik TreeListView to display some hierachical data no problems.
At the end of a branch we might need to display a list of related objects.
I'd like to use the RowDetailsTemplate for this.
My Question - is it possible to use a RowDetails template inside a TreeListView control?
I know you can with the GridView - but not seen any examples of how it would work with a TreeListView.
TIA
J
Seems to be possible docs.telerik.com
UPDATE
This piece of XAML code is acceptable:
<RadTreeListView Name="example">
<RadTreeListView.RowDetailsTemplate>
<DataTemplate>
<Views:DetailPositionView HorizontalAlignment="Left" />
</DataTemplate>
</RadTreeListView.RowDetailsTemplate>
</RadTreeListView>

MVVM and dynamic generation of controls

i've written a tool that generates sql queries using GUI, i want to rewrite the tool using MVVM and WPF, every sql column type has a different control as you can see in the following image
i add a column filter control based on the sql column type, and i generate the controls using code, just like i used to do in windows forms.
in MVVM i've read that the view is writtien enteirly using XAML,
does MVVM suite such application where i have to add different user
controls dynamically to a stack panel?
The controls won't exist in the view unless some column is double clicked, that means the control won't be available in the xaml and won't be hidden or collapsed.
is there any way that i can avoid the bindings in the code behind?
should i create a user control for each column type?
in general what is the best approach to devlop such application with complex and dynamic ui using mvvm?
Guess I know how to achieve that, but it is very complex stuff. First you should comprehend MVVM basic concepts.
Main ViewModel should be a class with ObservableCollection of ViewModels, each of them represents a column with its data and properties.
interface IViewModel : INotifyPropertyChanged,IDisposable
{
}
interface IColumnViewModel : IViewModel
{
}
class ViewModelBase : IViewModel
{
// ... MVVM basics, PropertyChanged etc. ...
}
class MainViewModel : ViewModelBase
{
ObservableCollection<IColumnViewModel> Columns {get; set}
}
In View I suppose something like ItemsControl with ItemTemplate, that should embed ContentControl with DataTemplate, that shall be automatically selected by WPF according to binded DataContext of list item. StackPanel itself is not suitable for that, but it can be invoked as ItemsPanelTemplate
<Window
xmlns:v="clr-namespace:WpfApplication.Views"
xmlns:vm="clr-namespace:WpfApplication.ViewModels">
<Window.Resources>
<DataTemplate DataType="{x:Type TypeName=vm:TextColumnViewModel}">
<v:TextColumnView/>
</DataTemplate>
</Window.Resources>
<ItemsControl
ItemsSource="{Binding Columns}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
So, you should build View/ViewModel pair for every column type.
Hope, my example will help. Good luck with your girlfriend and MVVM :)
If I've understood your scenario correctly :
You can use Data Templates & Items Templates
For example I've written an application which loads Data into Collection and then shows each item of that collection in a Wrap Panel [ Or stack panel ] based on defined data template.
And Wrap penel items are in sync by the collection itself within two way binding
You should consider using Observable Collections to achieve this goal
Then you can fill the collection and see the results on a view
I hope this helps
To write something like this in MVVM, you would have one view that is say, your content area. That view would have a view model, one of the properties of that view model would be a view, or several properties of that view model would be a view. It takes a bit to wrap your head around at times, but if you use Inversion of Control and Dependency Injection properly a view of views is very manageable in an MVVM pattern.
Well, your view isn't written entirely in XAML - you generate controls in C#.
I don't think you'll gain something from rewriting this and fitting it into an MVVM mold. Just keep the code as it is now and enjoy.

Editing ListBox with Live/Preview?

I am currently customizing a ListBox. With that I mean adding an image-element, second line-element etc. to one listItem.
The itemSource is a List in C#, therefore I have no preview of the items in Expression Blend/VS. And that's the pain.
Because I have always to edit the XAML and then deploy to check. And this goes on and on until the last pixel is correct.
Isn't there a way, of editing a ListBox with custom items (with a dynamic itemSource) live in Blend/VS?
That would really fasten up my developing.
If you want to see how your controls look like in design time, you must use SampleData. There are several ways to do it, it depends on your framework.
Let's say you have a page named MainPage.xaml. If you don't have view model already, create a new one and name it MainViewModel.cs. Define all public properties that will be used for binding.
Once you have your view model, create new file in a folder named SampleData and name it MainViewModelSampleData.xaml.
Now, in the MainPage.xaml add the following attribute to the page element:
d:DataContext={d:DesignData Source=SampleData/MainViewModelSampleData.xaml}
Also set Build Action for MainViewModelSampleData.xaml to DesignData.
Now, if you want to display data in your MainPage, you need to define all properties in the sample data file. For example:
// view model contains public properties Title of type string and Children of type
// PersonViewModel which contains properties Name and Age (string and int respectively)
<local:MainViewModel xmlns:local="clr-namespace:myapp"
Title="Title">
<local:MainViewModel.Children>
<local:ChildViewModel Name="John" Age="31" />
</local:MainViewModel.Children>
</local:MainViewModel>
You should now see your page filled with data in your design view. This way by using MVVM you can create mock data quickly. That will ensure that you can design your view around existing data without running the application.
Read more on the following links:
31 Days of Mango | Day #18: Using Sample Data
Modify sample data
Generate sample data
Using Blend Sample data at Design time and real data at Runtime
I now know how to do that.
If anyone if you guys ever stumble upon this problem, do this:
Copy all the XAML you wrote in the stackpanel of your itemtemplate
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
//...
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
And copy it up to <ListBox> //Here </ListBox>
There you can edit it in the designer.
And when you're done, just copy the code back to the StackPanel.

Categories