Dynamic column binding in Xaml - xaml

This is a follow up question from an earlier post (here).
I have some 'header' information stored as:
Dictionary<string,string> - where the first string represents the field name, and the second the heading I want displayed.
I have a set of dynamic data that is stored as:
Dictionary<string, object> - where string is the field name.
I bind to this in xaml as:
<data:DataGrid Name="_dataGrid" AutoGenerateColumns="True" IsReadOnly="False" Margin="5" Height="200">
<data:DataGrid.Columns>
<data:DataGridTextColumn Header="Forename" CanUserSort="True" SortMemberPath="Forename"
Binding="{Binding Converter={StaticResource RowIndexConverter},
ConverterParameter=Forename}"/>
<data:DataGridTextColumn Header="Surname" CanUserSort="True" SortMemberPath="Surname"
Binding="{Binding Converter={StaticResource RowIndexConverter},
ConverterParameter=Surname}"/>
<data:DataGridTextColumn Header="Age" CanUserSort="True" SortMemberPath="Age"
Binding="{Binding Converter={StaticResource RowIndexConverter},
ConverterParameter=Age}"/>
<data:DataGridTextColumn Header="Shoesize" CanUserSort="True" SortMemberPath="Shoesize"
Binding="{Binding Converter={StaticResource RowIndexConverter},
ConverterParameter=Shoesize}"/>
</data:DataGrid.Columns>
</data:DataGrid>
Problem 1 I want to autogenerate these columns (using the header information supplied)
Problem 2 I want the columns to be generated based on what datatype they are (i.e. boolean = checkbox)
Problem 3 Ideally I would also like to specify weather a button should exist in the first column or not (i.e. an edit / view button) via databinding

I've used an approach that follows the pattern of this pseudocode
columns = New DynamicTypeColumnList()
columns.Add(New DynamicTypeColumn("Name", GetType(String)))
dynamicType = DynamicTypeHelper.GetDynamicType(columns)
DynamicTypeHelper.GetDynamicType() generates a type with simple properties. See this post for the details on how to generate such a type
Then to actually use the type, do something like this
Dim rows as List(Of DynamicItem)
Dim row As DynamicItem = CType(Activator.CreateInstance(dynamicType), DynamicItem)
row("Name") = "Foo"
rows.Add(row)
dataGrid.DataContext = rows

Related

DataGridComboBoxColumn show Foreign Key Table - WPF

I have an SQL Database, with table Jars and JarTypes. I need to show the data in a DataGrid. I also have to be able to edit the rows. I think a DataGridComboBoxColumn is perfect for the job. How can i populate the ComboBox with JarTypes.Type and put TypeId back into the Jars.TypeId. The tables are stored in DataTables JarsDt and TypeDt
Jars (JarsDt)
JarId (PK)
Amount
TypeId (FK)
JarTypes (TypeDt)
TypeId (PK)
Type
XAML
<DataGrid x:Name="JarDataGrid"
AutoGenerateColumns="False"
IsReadOnly="False"
HorizontalAlignment="Stretch"
Margin="10,35,2,36.8">
<DataGrid.Columns>
<DataGridTextColumn Header="#"
IsReadOnly="True"
Binding="{Binding JarId}" />
<DataGridTextColumn Header="Mengde"
Binding="{Binding Amount}" />
<DataGridComboBoxColumn x:Name="combo"
Header="Glass"
SelectedValueBinding="{Binding TypeId}"
DisplayMemberPath="{Binding Type}"/>
<DataGridTextColumn Header="Mengde levert"
IsReadOnly="True"
Binding="{Binding AmountDelivered}" />
Set the ItemsSource property of the DataGrid to a list of Jars and the ItemsSource property of the ComboBox to a list of JarTypes.
You can do this in XAML using a CollectionViewSource or in code by directly setting JarDataGrid.ItemsSource = ListOfJars.
You need to set the SelectedValuePath property of DataGridComboBoxColumn.
Also DisplayMemberPath is a string property, so does not use binding.
In your case it would be:
<DataGridComboBoxColumn x:Name="combo"
Header="Glass"
DataContext="{StaticResource jarTypesViewSource}"
ItemsSource="{Binding}"
SelectedValueBinding="{Binding TypeId}"
SelectedValuePath="TypeId"
DisplayMemberPath="Type"/>

Disable Certain Grid Column

I was wondering if it's possible to make a case or an if statement or a trigger of some sort within the XAML? My goal is to make the column header with the name ID Isvisible = false My columns are autogenerated which makes it a bit more tough. If I can help with making the column visibility please.
<telerik:RadGridView ItemsSource="{Binding AllQueries, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="True">
</telerik:RadGridView>
AllQueries is very dynamic, the columns changes based on certain actions but here is a sample.
AllQueries = (from z in ctx.Projects
join y in ctx.ProjectScopes on z.ProjectScope_Id equals y.Id
where (z.StartDate <= StartDateTo && z.EndDate >= EndDateTo && y.Value == "Community Development")
select new {Id = z.Id, z.Created, z.EndDate, z.ProjectName }).ToList();
I would like to display Created, EndDate and ProjectName. I cannot remove ID because it plays a roll on my double click action.
You'll have to explicitly set in the XAML inside the Column Template to disable a certain Column.
<telerik:RadGridView ItemsSource="{Binding AllQueries, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="True">
<!-- GridView's Column Template
<telerik:Column IsEnabled="False"> -- I'm not sure what is the exact control name for `Telerik's RadGridView Column` and if it requires setting binding to know what field it will map in the column.
-->
</telerik:RadGridView>
UPDATE
It can be similar to this
<DataGrid Name="dealerList" AutoGenerateColumns="False" ItemsSource="{Binding DealerList}">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Width="30" Binding="{DealerId}" IsEnabled="False" />
<DataGridTextColumn Header="Name" Width="*" Binding="{DealerName}" />
</DataGrid.Columns>
</DataGrid>

How do I refer to simple strings bound to a Silverlight Toolkit ListPicker in a DataTemplate?

I am styling the ListPicker with a DataTemplate. All the examples I have read assume that the ListItems are bound complex objects and so can refer to properties on the objects using the usual Binding Property syntax. e.g.
this.myListPicker.Items.Add(new Profile() { Name = "Joe",
Occupation="Button pusher" });
and in the XAML,
<DataTemplate>
<StackPanel>
<TextBox Text="{Binding Name}" />
<TextBox Text="{Binding Occupation}" />
</StackPanel>
</DataTemplate>
However my ListPickers are bound to a List of simple strings and there does not seem to be a property on the string that actually refers to the string.
How do I get a handle to the string inside the DataTemplate so that I can assign them to a e.g. TextBox in the template?
In the example code you show, you do actually have a "complex" object, a Profile, and the binding you specify should work.
If you really just have strings as the items, then the binding in your ItemTemplate would look like:
<TextBox Text="{Binding }" />
The relevant detail is that all ItemsControls (and ListPicker seems to be one) set the DataContext of the view of each item to the item. The binding syntax, above, means "bind to the source itself", and, unless otherwise specified (like with Source or RelativeSource, etc.), the source of any binding is the DataContext.
MSDN has more details here.

Silverlight Find Control in Data Template

I have the following xaml code:
<dxb:BarButtonItem Name="btnPrev" Cursor="Hand" ItemClick="btnPrev_ItemClick">
<dxb:BarButtonItem.ContentTemplate>
<DataTemplate>
<Image x:Name="imgSkipLeft" Source="/ProjectTool;component/images/arrowleft.png" Height="16" Width="16">
<ToolTipService.ToolTip>
<TextBlock x:Name="txtBlockTip_Left"/>
</ToolTipService.ToolTip>
</Image>
</DataTemplate>
</dxb:BarButtonItem.ContentTemplate>
</dxb:BarButtonItem>
How can I find txtBlockTip_Left and modify the text
Rather that trying to find the TextBlock on the DataTemplate to change the text it would be better to set the text through a binding and then change the property that the Text property is bound to. The following resource has an example on how to use data binding within a DataTemplate: http://www.silverlight.net/learn/data-networking/binding/data-binding-to-controls-%28silverlight-quickstart%29
Using the VisualTreeHelperExtensions class and put a grid inside the data template and give it a name, in the example below the name is grdTemplate.
var bttn= btnPrev.ItemContainerGenerator.ContainerFromItem(btnPrev);
var dataTemplate = bttn.GetDescendantsOfType<Grid>().FirstOrDefault(g => g.Name == ("grdTemplate"));
var textBlocks= VisualTreeHelperExtensions.GetDescendantsOfType<TextBlock>(dataTemplate);
TextBlock txtBlockTip_left = textBlocks.ElementAt(0);

How to programmatically create rectangle and textblock with binding element with c#?

I have the following code, which i want to programmatically create. Where the i is must be an integer into xaml! This is a sample Code from VISIBLOX.
<Rectangle Margin="20,0,0,5" Height="10" Width="10" Fill="{Binding ElementName=chart, Path=Series[i].LineStroke}" VerticalAlignment="Center" />
<TextBlock Margin="4,0,0,0" Text="{Binding ElementName=chart, Path=Series[i].DataSeries.Title}" />
<TextBlock Margin="4,0,0,0" Text="(" HorizontalAlignment="Left" />
<TextBlock Text="{Binding ElementName=chart, Path=Behaviour.Behaviours[0].CurrentPoints[i].Y, StringFormat=0.00}" Width="38" />
<TextBlock Text=")" HorizontalAlignment="Right" />
I can create a most programmatically but im stucking since 2 days with the Path=Behaviour.Behaviours[0].CurrentPoints[i].Y impossible for me to see how i can programmatically create it!
Thank u for help
Edit
IT's Work
TextBlock txtBlock3 = new TextBlock();
Binding txtBinding3 = new Binding();
txtBinding3.ElementName = "MainChart";
txtBinding3.Path = new PropertyPath("Behaviour.Behaviours[0].CurrentPoints[" + index +"].Y");
txtBlock3.SetBinding(TextBlock.TextProperty, txtBinding3);
txtBlock3.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
Panel.Children.Add(txtBlock3);
Presumably you're going to be building this Binding in a for loop of some sort?
If so, can't you do something like:
Binding b = new Binding { Path = new PropertyPath("Behaviour.Behaviours[0].CurrentPoints[" + i +"].Y”) };
Where the i there is the indexer in the for loop? I'm not sure I fully understand the problem so maybe you could elaborate with a bit more context?
If you’re trying to bind to a different thing depending on what is available in CurrentPoints, you might need to just bind to Benaviour.Behaviours[0] and use a converter to return the correct point’s Y value.
If you need any more help just let me know!