Binding datatable to combobox of datagrid in wpf - c#

Hi I have to create a wpf grid which is having combo box in it . I have to bind grid to a data table dtGrid and combobox item source to a datatable dtcmb . I wrote template below for embedding combo box in grid .
Now I need to access the combo in code behind to specify item source and DisplayMemberPath, ,SelectedValuePath,SelectedValue,
Even though i could access data grid in code behind I could not access combo box . what is the prob ?
<my:DataGridTemplateColumn x:Name="supplierName" Header="Supplier" Width="60" >
<my:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox x:Name="cmbSubSysSupplier_SRV" IsTextSearchEnabled="True"
Height="23" ItemsSource="{Binding}" Width="80" />
</DataTemplate>
</my:DataGridTemplateColumn.CellTemplate>
</my:DataGridTemplateColumn>

You should use a DataGridComboBoxColumn for this particular case. You can access it in code behind through its x:Name property. The DataGridComboBoxColumn object will give you access to all the properties you need.

Related

ComboBox IsChecked Binding not working in Data Template

I have a ComboBox with a Textblock and a Checkbox displayed to allow me to set a view model boolean property based off the checkbox.
View Code
<ComboBox HorizontalAlignment="Left" IsEditable="True" IsReadOnly="True" Text="-- Filter Columns --">
<ComboBoxItem>
<ComboBoxItem.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Description"/>
<CheckBox IsChecked="{Binding DescriptionHeaderVisibility}"/>
</StackPanel>
</DataTemplate>
</ComboBoxItem.ContentTemplate>
</ComboBoxItem>
</ComboBox>
View Model Property
public bool DescriptionHeaderVisibility
{
get => _descriptionHeaderVisibility;
set => Set(ref _descriptionHeaderVisibility, value);
}
Useful information
I am using MVVM Light
If I do the exact same check box binding somewhere else on the page, it works and notifies my view model of the change.
Binding only does not work within the templated combo box
I am not sure why the binding is not working within the combo box template? Am I just missing something here that I don't know about? If I can get this binding to work properly the plan is to add another few rows of text blocks and check boxes all bound to different boolean properties in my view model.
Picture of drop down box
The problem is, you are using a ContentTemplate, but you do not give it any Content to display. If you just want to use the surrounding DataContext, you could write
<ComboBoxItem Content="{Binding .}">
Inspired by this answer to a similar question.

How to access buttons in DataGrid cells (column/row) programmatically in c#?

I have a DataGrid that has (editable) columns bound to items of a ObservableCollection.
In addition each row has a "Save" button defined in XAML as
<DataGrid Name="myDataGrid" AutoGenerateColumns="False" ...
<DataGridTemplateColumn >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Save" Click="OnSave"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Whether or not a button of a row is enabled depends on item properties in connection with authorization rules implemented in c#.
In addition the Button Content should change depending on the language that the user selects (which the user can do at any time).
So I have the need to somehow get access to the button objects in c# code but haven't found a way to do this so far.

Combobox not rendering in wpf datafrid

I have my data grid "dgSubsytem" column defined like below
<my:DataGridComboBoxColumn x:Name="cmbSubSysSupplier_SRV" Header="Supplier" Width="160"
ItemsSource="{Binding RelativeSource}" SelectedValueBinding="{Binding SupplierId}" />
As you see from the code i am having a combo box inside a grid .
Item source of this combo box is a datatable which is bound to it in the code behind .
Item source of the grid also another datatable bound in code behind .
code of binding item source of combobox in code behind is as follows
cmbSubSysSupplier_SRV.ItemsSource = dsComboBox.Tables[3].DefaultView;
cmbSubSysSupplier_SRV.DisplayMemberPath="FullName" ;
cmbSubSysSupplier_SRV.SelectedValuePath = "SupplierId";
Problem is combo box itself not rendering . But I can see the value of the Supplier rendered as text . What is the problem?
There are 2 parts here:
List of values to be populated in ComboBox: ItemsSource, should be bound using a StaticResource, with a List<X> fields exposed from your ViewModel.
The actual value (here X) should be bound to SelectedItemBinding using binding to data item.
No binding in code behind required.
At what point does your code-behind stuff run?
You're setting the ItemsSource in two places - in the XAML and in the Code-Behind. Whichever one runs second will overwrite the value of the first one, so only the last value set will be used.
I suspect your XAML is getting run last, and RelativeSource is probably not a property on your DataContext, so your ComboBox ends up being bound to nothing.
To fix it, simply remove your ItemsSource binding in the XAML for the DataGridComboBoxColumn
<my:DataGridComboBoxColumn x:Name="cmbSubSysSupplier_SRV"
Header="Supplier" Width="160"
SelectedValueBinding="{Binding SupplierId}" />
In addition, the DefaultView of a DataTable will return an object of type DataView, and DataView does not have properties called FullName or SupplierId, so your SelectedValuePath and DisplayMemberPath properties won't work.
I'd recommend building a list of KeyValuePair<int,string> out of your data items, and bind your ComboBoxColumn.ItemsSource to that list, then switch the SelectedValuePath to "Key" and the DisplayMemberPath to "Value"
I personally fought with DataGridComboBoxColumn for long time and i think the way is to use DataGridTemplateColumn. Here is an exemple :
Looks a lot of code but evective.
Put the collection as resource :
<Grid.Resources>
<CollectionViewSource x:Key="StructuresCollection" Source="{Binding StructuresList, Mode=OneTime}"/>
</Grid.Resources>
<DataGridTemplateColumn Header="Structure" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Structures.Name}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate >
<DataTemplate>
<ComboBox x:Name="CStructures" SelectedItem="{Binding Structures}" DisplayMemberPath="Name" SelectedValue="{Binding IDStructure, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="{Binding IDStructure}" ItemsSource="{Binding Source={StaticResource StructuresCollection}}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

Can we have a grid inside the cell of the DataGrid in WPF?

I require to have a DataGrid having multiple rows and 3 columns. Now each cell of the DataGrid is to show some information (6 to 8 parameters) and a button. On click of this button a pop-up is to be shown.
Now for displaying the data inside the cell of the DataGrid, I need to align them properly and was thinking of using the Grid. How to achieve this.
Also how do I get to know at the click event of the button that which cell button was clicked ?
Kindly help.
You may add DataGridTemplateColumn(s) to your DataGrid, and then define usual data template for the column:
<DataGrid.Columns>
<DataGridTemplateColumn Header="Foo" Width="SizeToCells">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
...
<Button Command="{Binding SomeCommand}" />
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGrid.Columns>
Now about the click event. Bind your grid with items source. Each item in that source must be a view model with any ICommand property. Bind this property to the button's command in cell template, and you will get it.

C# Silverlight - Combobox with TwoWay Binding?

EDIT:
The Answer I was looking for was....
<dataFormToolkit:DataField Label="Business Type:">
<ComboBox x:Name="BusinessType" SelectedItem="{Binding BusinessType, Mode=TwoWay}" >
<ComboBox.Items>
<sys:String>Land</sys:String>
<sys:String>Maritime</sys:String>
</ComboBox.Items>
</ComboBox>
</dataFormToolkit:DataField>
Heres the link to the article
I have a c# silverlight business application that uses the ado.net entity framework and the domain service class to bind to my sql server database and pull data from/ persist data to my database. I have been using the dataformtoolkit namespace to layout textboxes which can be edited/display data, using a TwoWay binding mode in order to allow the read/write functionality.
On some of the fields I want to use a combobox instead of a textbox in order to add a better user experience to my application. The impression i've got from reading around the web is that this isnt as easy as it should be.
My current textbox code looks like:
<dataFormToolkit:DataField>
<TextBox Text="{Binding BusinessType, Mode=TwoWay}" />
</dataFormToolkit:DataField>
my attempt at something similar is as follows but incorrect:
<ComboBox>
<ComboBox.Items>
<ComboBoxItem Content="Maritime" IsSelected="{Binding BusinessType, Mode=TwoWay}" />
<ComboBoxItem Content="Land" IsSelected="{Binding BusinessType, Mode=TwoWay}" />
</ComboBox.Items>
</ComboBox>
NB/ I want the combobox to be populated by a list or an enum etc. (preferably a list). The contents of the combobox should have nothing to do with the database, just that when the user hits submit the selection made in the combobox gets persisted back to the database. It is also important that the combobox can read from the database and display the specific selection that has already been made if this is the case.
****EDIT:
Current setup of dataform bound to datagrid with editable businesstype field as a textbox (I want to replace this textbox with a combobox that has two selectable items).
<!--DataForm Declaration-->
<dataFormToolkit:DataForm x:Name="dataForm1" Height="410" Width="331"
VerticalAlignment="Top"
Header="Job Details"
CurrentItem="{Binding SelectedItem, ElementName=dataGrid1}"
HorizontalAlignment="Left" >
<dataFormToolkit:DataForm.EditTemplate>
<DataTemplate>
<StackPanel>
<dataFormToolkit:DataField>
<TextBox Text="{Binding BusinessType, Mode=TwoWay}" />
</dataFormToolkit:DataField>
</StackPanel>
</DataTemplate>
</dataFormToolkit:DataForm.EditTemplate>
</dataFormToolkit:DataForm>
So how do i manipulate this code to use a combobox instead of a textbox?
Any help in doing this would be greatly appreciated.
You should setup your binding to use the ComboBox's SelectedValue property.
<ComboBox SelectedValue="{Binding BusinessType, Mode=TwoWay}">...</ComboBox>
The problem with this is that the ListBox and ComboBox will use the Equals() method on the object in the SelectedItem so if the types do not match then the ComboBox will not set the appropriate item as selected. Therefore, BusinessType will need to be a string since you are using ComboBoxItem's and specifying string content.
If bound the ItemsSource of the ComboBox then you would use SelectedItem and it would actually be an entity type as well, in which case you have more flexability/control around what equals what.

Categories