Grid with content from Binding - wpf

I have a library that generates a Grid based on input parameters. The Grid may contain different controls based on the input. I want to create a ListBox where each list item will get its own generated Grid. Is this doable? I couldnt find any Panel-derived (Gird, StackPanel etc) that expose the Content property like Button for example.

How are you passing the data to build the Grid?
I'll assume you have a control that receives the data via a Dependency Property. I.e. you have something like MyControl.MyData property, where MyData is a Dependency Property. In that case, try using a DataTemplate.
Make an ObservableCollection where each item is the data you need to pass in order to build the grid.
On the instance of the ListBox, define ItemTemplate to use a DataTemplate consisting of your control.
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<myAssembly:MyControl MyData="{Binding }"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

#XAMeLi is almost right on the money with his answer - what would be better is a DataTemplateSelector, that way each data item can have a different template (or generated grid). In your class that extends DataTemplateSelector you can easily generate or load the appropriate grid layout as either a separate control or as a dynamic DataTemplate.
Check this article for a good example: WPF Tutorial - How To Use A DataTemplateSelector

Related

How can i Create a wpf Datagrid view with dynamically generating combobox columns

How can i Create a Datagrid view with dynamically generating combobox (through c#) columns and how can i bind the data to those dynamically generated columns (through MVVM).
i want to generate different collection of data to each combobox inside the automatically generated column.
Thanks in advance.
Not sure why you want to add the combobox via c#.
Why not use a Template Column where you take advantage of MVVM as you should do. View is defined in XAML and content is bound via ViewModel data.
<DataGridTemplateColumn Header="ColumnHeader">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<local:CostumControlWithCombobox Text="{Binding Path=YourListToPickFrom}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
If the pick lists should be possibly different for certain row. You need a rule or a parameter how to bind the matching list. Note that it is also possible to add controls with mvvm behavior in a TemplateColumn (just for the sake of demonstration) but you could also bind to a combobox list itself.
If you still prefer to build this up via C# code Check out the Class documentation of DataGridTemplateColumn they can also be accessed via code.
https://msdn.microsoft.com/en-us/library/system.windows.controls.datagridtemplatecolumn(v=vs.110).aspx
HTH

How to render different template for some tabs in WPF?

I have a tab content template set to my tab control:
<TabControl SelectedIndex="0"
ItemsSource="{Binding Tabs}"
ItemTemplate="{StaticResource AppTabItemTemplate}"
ContentTemplate="{StaticResource AppTabContentTemplate}" />
The thing is that most of the times the current template is wanted, but there are times when I want to display another template instead. The item source provides this data whether it should show one or another, but how can I do an "if" in XAML and use an alternative UI when the other layout is wanted?
Should this logic be part of the template or the containing XAML that includes this tab control? The information that is used to make the decision between UIs is in the item source.
Use a DataTemplateSelector.
You will need to define your selection logic in a class that derives DataTemplateSelector, create a resource for your selector in XAML and then use it by assigning the resource to the ItemTemplateSelector property of your tab control.

Create a control after selecting Item from grid in MVVM

I have a collection of items in grid(of telerik) and after I select any item of collection of items ( I know how to notice changing of selected item) I need to create a control in the same user control which will display some property of selected item.
The problem is that depending of what type(the class of collection have a field SomeType) of selected item is, I need to add a specific class.
So for example if I had a collection of cars, and I selected car which was suv, than I would had to add SuvControl, and when I selected van, then I would had to add VanControl. Those controls are different because have different names of fields and would have different behaviors.
I'm using MVVM Light .
I couldn't find any good example so I'll reward even for a link to some example.
What I would do would be binding the SelectedItem [property of the ListBox to the view model
SelectedItem={Binding SelectedItem, Mode=TwoWay}
or you could do ElementName binding too - all this to get to the details view's viewmodel.
The details view would use a DataTemplateSelector and you would display your details view like this:
<Grid
x:Name="DetailsGrid">
<prismvm:DataTemplateSelector
Content={Binding SelectedItem}>
<prismvm:DataTemplateSelector.Resources>
<DataTemplate
x:Key="Type1ViewModel">
<views:Type1View/>
</DataTemplate>
<DataTemplate
x:Key="Type2ViewModel">
<views:Type2View/>
</DataTemplate>
</prismvm:DataTemplateSelector.Resources>
</prismvm:DataTemplateSelector>
</Grid>
As suggested the DataTemplateSelector is the right way to go in most cases, and certainly the cleanest.
An alternative when you have few different templates (2 or 3) if to put them all and bind their visibility to the item type property so only one is visible at a time. Again, this is nor the recommended technique but in simple cases it can bring you to the desired result quickly.

How to present a collection of objects in a listbox in WPF

I have a collection of objects that I want to present. How can I do this? A listbox would do but each object has many attributes which I want to present. I already bound a listbox to a collection and I have all my objects listed. My question is regarding the visualization of the listbox and if the listbox is the correct thing to use or there is something else that I should use.
I find the existing answers to be a bit lacking, normally one would not process collections or boil their items down to a string, at the very best you would do some dynamic manipulation using a CollectionView (e.g. sorting, grouping), but normally you use Data Templating to display the individual items which allows you to use all their properties.
Further there are several controls which work well with collections, firstly you need to know if you want selection, if not an ItemsControl is a good choice, otherwise you should use a ListBox or ListView.
ListViews are normally employed if you have different views for your objects, e.g. a details view and a thumbnail view. You can use the ListView.View for this, there is one existing view in the framework, the GridView, which offers columns. What Matthew Ferreira suggested is exactly what you should not do with a ListView since you want to make the templates dependent on the current view, in fact that code does not even compile since DataTemplate can only have one child.
ListViews are supposed to encapsulate the view logic in their view so it can be changed at will. If you decide to use a ItemsControl or ListBox then setting the ItemTemplate is what you want to do. Read the Data Templating overview i linked to, it makes for a good starting point.
You might want to consider using a ListView control instead. ListView has support for columns if you are planning on showing several properties from your object. You can use the ItemTemplate property to format the display of your object. For example:
<ListView ItemsSource="{Binding Path=myObjectCollection}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Title}"/>
<CheckBox IsChecked="{Binding Path=ShouldCheck}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
This example assumes that your object has the properties Title and ShouldCheck.
Your collection of object is probably to be viewed as your model. The usual thing in WPF is to add a ViewModel that translates and exposes the model data into a form suitable for binding. Depending on what you want to do, your VM could e.g. format each object into a string representation and then expose it as a collection of strings that the Listbox can bind to and display.

How to bind StackPanel Children from a ViewModel?

New to Silverlight. I'm working on a chat application where new chat messages are added to the bottom of a list. I had a working version that used as StackPanel inside a ScrollViewer and then in some code behind used StackPanel.Children.Add().
I'm trying to convert this to a View-ViewModel approach, and I can't figure out how to bind the Children of the StackPanel to any collection property. I've tried this:
<ScrollViewer Name="scrollMessages" Grid.Row="2" Margin="0,0,0,0" VerticalScrollBarVisibility="Visible">
<StackPanel x:Name="pnlMessages" Orientation="Vertical" Children="{Binding Path=ExampleTBs}" />
</ScrollViewer>
where ExampleTBs is a collection of TextBlocks created in code. This fails XAML parsing, the Children property isn't bindable in this way.
Is the approach of binding to the StackPanel itself fixable? Should I be using a different container type? I saw another question where the guy created the entire StackPanel in code and then used a ContentPresenter...
Bottom line, I'd like to find a way to databind my view to a viewmodel using something like a StackPanel as a container where successive items will be added to the container over time. Best approach?
Use a ListBox (or any other ItemsControl) and bind the ItemsSource property to an ObservableCollection in your ViewModel.
Do you need to use a StackPanel? If you use an ItemsControl instead, this still presents each chat message in a vertical list, and also allows for binding of the data.

Resources