How to bind datatable value to checkbox and combobox value? - c#

In Old Ver. of My code I am binding
dgvShow.Columns["grdTest_Active"].DataPropertyName = oDTList.Columns["STATUS"].ToString();
dgvShow.Columns["grdTest_LnkOrder"].DataPropertyName = oDTList.Columns["ORDER"].ToString();
I am converting the code in WPF and I have taken a grid and in that I have placed
<DataGridTemplateColumn Header="Active" Width="50" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox x:Name="chkActive" IsChecked="{Binding Path=Active}" HorizontalAlignment="Center" VerticalAlignment="Center" IsEnabled="True"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Order" Width="60" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Path=Order}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
when I am using
DataGridObjectTypeList.DataContext = oDTList.DefaultView;
on vmUCObjType Cs file It is binding the grid but, checkbox and combobox data is not showing.
I want to bind oDTList datatable value to my checkbox and combobox how to do that?
Please some one help me I am new in WPF.

In your XAML file, write
<ComboBox x:Name="Name_ComboBox" DisplayMemberPath="Name" SelectedValuePath="id"/>
In your code behind, put:
Name_ComboBox.ItemSource = Table_name;
(Table_name being a reference to the table you mentioned).
then you can reach the id of the currently selected person in the combo box using the expression:
Name_ComboBox.SelectedValue

I have removed ComboBoxColumn and added DataGridComboBoxColumn in front end and in code behind I have done something like this:
((DataGridComboBoxColumn)dgShowList.Columns[1]).ItemsSource = DTCount.DefaultView;
((DataGridComboBoxColumn)dgShowList.Columns[1]).DisplayMemberPath = DTCount.Columns["Order"].ToString();
((DataGridComboBoxColumn)dgShowList.Columns[1]).SelectedValuePath = DTCount.Columns["Order"].ToString();
((DataGridComboBoxColumn)dgShowList.Columns[1]).SelectedValueBinding = new Binding("Order");

Related

WPF DataGrid does not save changed value to variable

So, I have this little WPF snippet:
<DataGrid x:Name="lstCategories" AutoGenerateColumns="False" Grid.Row="0"
Margin="5,5,5,5" ScrollViewer.CanContentScroll="True" SelectionMode="Single" CanUserSortColumns="False" CanUserReorderColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<DataGridColumnHeader Tag="All" Click="DataGridColumnHeader_Click">All</DataGridColumnHeader>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding enabled}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Category" Width="Auto" IsReadOnly="True" Binding="{Binding category}" />
</DataGrid.Columns>
</DataGrid>
Which displays data as given in:
lstCategories.ItemsSource = categoryList;
Now, when the user clicks the checkbox, I'd expect the datagrid to write this change to categoryListItem.enabled, but when I check the value, it says true no matter what.
How can I make the DataGrid store changes to the variable it uses as data source?
Additional Info: I've chosen the TemplateColumn-approach with an embedded checkbox because this way the user does not have to click two times to modify the check box.
Update 1:
I've updated the XAML to incorporate TwoWay-Binding as:
<CheckBox IsChecked="{Binding enabled, Mode=TwoWay}"/>
The data source variable still does not get updated.
I see you've already figured out Mode=TwoWay (which isn't necessary anyway, as it is the default if you don't explicitly set it). Now all you have to do is set UpdateSourceTrigger to PropertyChanged.
<DataTemplate>
<CheckBox IsChecked="{Binding enabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>

Can't see Textbox text in DataGrid

I am trying to make a DataGrid in WPF that will display the different properties of the items in a given collection. So far, everything works perfectly, except for one. Here is an image of my DataGrid, which is fully populated just as intended:
And you may already see my problem. Each and every item has a value associated with it, which is properly binded. However, I cannot see the value for any of the items unless I specifically click on that cell. For example:
I want the values to be visible at all times, just like the Name and Default Value Columns, but it is very important that the value, and only the value, is editable from the DataGrid at runtime. Here is the XAML I have in place for the datagrid:
<DataGrid Margin="20" AutoGenerateColumns="False" ItemsSource="{Binding ConfigurationParameterCollection}" Name="MasterListBox" ScrollViewer.VerticalScrollBarVisibility="Visible" SelectionChanged="MasterListBox_SelectionChanged" AlternationCount="2" DockPanel.Dock="Top" HorizontalAlignment="Center" Width="1000" >
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
<!-- Begin Problem Area-->
<DataGridTemplateColumn Header="Value">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=Value, Mode=TwoWay}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<!-- End Problem Area-->
<DataGridTextColumn Header="Default Value" Binding="{Binding DefaultValue}"/>
</DataGrid.Columns>
</DataGrid>
Don't worry about the name of the DataGrid, it used to be a ListBox and I just never bothered to change the name. Everything links up perfectly, I just can't figure out why the TextBox text is not visible.
Any help you can give is much appreciated.
EDIT
I know that I can achieve this with using CellTemplate instead of CellEditingTemplate, but the latter has the feature of only editing on two clicks, but selecting the row otherwise. I want to have this feature, so If there is a way to do that with CellTemplate please let me know. With CellTemplate, I see the boxes at all times:
I want it to be like in the second picture, where the rest of the column appears in style with the datagrid, while the cell I am editing looks like a text box.
Change
DataGridTemplateColumn.CellEditingTemplate
To
DataGridTemplateColumn.CellTemplate
You can specify a display template, and an edit template ...
<DataGridTemplateColumn Header="Value">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=Value, Mode=TwoWay}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Value, Mode=TwoWay}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

How to set template for DataGrid with ItemSource as DataTable using MVVM

My XAML:
<DataGrid Grid.Row="1" ItemsSource="{Binding PersonTable}" CanUserAddRows="False" CanUserDeleteRows="False"/>
My code in ViewModel:
PersonTable = new DataTable();
PersonTable.Columns.Add("Name");
PersonTable.Columns.Add("Delete");
I would like to get Button in AccessType column but:
DataRow dataRow = PersonTable.NewRow();
dataRow["Name"] = person.Name;
dataRow["Delete"] = new Button();
PersonTable.Rows.Add(dataRow);
Which creates cell with 'System.Windows.Controls.Button' value. I would like to achieve same behavior like using this xaml:
<DataGridTemplateColumn Header="Delete">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
How to use template when using DataTable? How bind for eg. color in Person to Cell in DataGrid?
EDIT:
Delete columns is an example. I don't know columns names and count of columns in advance.
EDIT2:
Because of misunderstanding: delete is only a example, I need to at 20 or more columns in runtime. I need to be able to put there buttons in cells and bind to properties.
A neat and nice approach would be
<DataGrid ItemsSource="{Binding PersonTable}"
AutoGenerateColumns="False"
CanUserAddRows="False" Grid.Row="1" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}"
Width="*"/>
<DataGridTemplateColumn Width="Auto" Header="Delete">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Delete"
Command="{Binding SomeCommand,
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
CommandParameter="{Binding}"
Margin="5"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
you can bind your command to delete button and perform actions.
You can create a custom DataGridColumnTemplateSelector.
The template selector will return the template of each datagrid column based on predefined convention (ex: prefix of the DataTable column names).
that way the template will remain dynamic and cusutomized
Your DataGrid :
<DataGrid x:Name="MyDataGrid1" HorizontalAlignment="Left" Margin="89,34,0,0" VerticalAlignment="Top" AutoGenerateColumns="False">
<DataGrid.Columns>
</DataGrid.Columns>
</DataGrid>
Now, we will use dynamic loading of XAML. For that we need markup in a separate text file. Change its Build Action to Content, and Copy To OutputDirectory to Always.
myDataGridCol.txt :
<DataGridTemplateColumn
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ToggleButton Content="{Binding ^colname^}" Background="Red">
</ToggleButton>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Adding columns dynamically to DataGrid can be done like so :
foreach (DataColumn col in PersonTable.Columns)
{
DataGridTemplateColumn dtcol;
using (StreamReader reader = new StreamReader(("32678595/DataGridTemplateColumn.txt")))
{
String xamlContent = reader.ReadToEnd();
xamlContent = xamlContent.Replace("^colname^", col.ColumnName);
dtcol = (DataGridTemplateColumn)(System.Windows.Markup.XamlReader.Parse(xamlContent));
}
dtcol.Header = col.ColumnName;
MyDataGrid1.Columns.Add(dtcol);
}
MyDataGrid1.ItemsSource = PersonTable.DefaultView;
And binding Color to a cell can be done using concept presented below :
<DataGridTemplateColumn Width="100" Header="Color">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label>
<Label.Background>
<SolidColorBrush x:Name="CellColor" Color="{Binding PropertyColor}"/>
</Label.Background>
</Label>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Now, that you know how to add columns dynamically and to bind background property. You can make your ViewModel accordingly.
And you can use Color col = (Color)ColorConverter.ConvertFromString(value); to convert String to Color for Binding ease.
And if you are using a String to store color value, then normal binding would work.
<Button Content="color" Background="{Binding PropertyColor}"/>

not able to make checkchange of checkbox inside datagrid

I have following datagrid having checkbox in first column:
I am not able to make checkbox selection-unselection when i run the code.
I have following code to have checkbox inside datagrid:
<DataGridTemplateColumn Width="50" Header="select">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
I am new with WPF Project.
Please guid me.

How to get the button and change its color when datagrid item selected?

I have a datagrid with button included and binded to image as shown. How to get the button control and change its forecolor when the datagrid item is selected.
<DataGrid Name="dgItems" AutoGenerateColumns="False" Grid.Row="1" Width="300" CanUserAddRows="False" SelectionChanged="dgItems_SelectionChanged">
<DataGrid.Columns>
<DataGridTemplateColumn Width="SizeToCells" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Name="btnImg" Click="btnImg_Click" Height="160" Width="270">
<Image Source="{Binding Path=ImgUrl}" />
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
As an example you could do something like this..
row.Cells[2].ButtonName.Style.BackColor = System.Drawing.Color.Red;
This is pseudo-code but you would have to know the actual cell based on the index this should be enough to get you started could you also post the code behind of the event you are trying to code the button change in..? thanks

Categories