I have a Combobox in a DataGrid which allows IsTextSearchEnabled. This works but the user is allowed to put their own text when the item is not found in the combobox. Is there a property that will stop this, or what can I do to stop the user adding their own text?
The xaml
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding DataContext.Types,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=Window}}"
x:Name="cmbDeploymentEditType"
SelectedItem="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValue="Type"
Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsTextSearchEnabled="True"
IsSynchronizedWithCurrentItem="False"
IsEditable="True">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
Thanks
There are multiple ways you can handle this, you can use a control that stops this like the XamMultiColumnComboEditor with CustomValueEnteredAction setting. Or you could do validation to enforce the rule you want.
Related
In the previous window I have a table. I can access specific data entries.
for example the code below takes the Description from the selected row, and places it inside of the textbox.
<TextBlock Text="Description" Style="{StaticResource tabTextBlock}"/>
<ComboBox ItemsSource="{Binding Vwr.Table.Tbl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Description" SelectedValuePath="Description"
SelectedIndex="{Binding Vwr.Table.SelectedRowIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding Vwr.Table.Vals[2].Val, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsEditable="True" Style="{StaticResource tabTextBox}" Height="54"/>
My question is:
How would I port the entire Table, so that it would be displayed in a DataGrid/Table format inside of an XAML Window?
Assuming your data context is similar to the example you gave, this should work:
<DataGrid ItemsSource="{Binding Vwr.Table.Tbl}" />
By default, the DataGrid will automatically generate columns for each property in the item type.
I have a View that displays a Part. All parts contain a list of identifiers. In my View I display Part Properties and a DataGrid with all the Identifiers of that part.
Now if I change a value of an identifier, I want another value update to the default. But if I change my identifier value and set the default of the other property - my DataGrid does not update. Only if I click on the cell, then it gets updated after losing focus.
How can I update the View automatically?
I guess the problem is that I do not want to update a direct property of the Part, but a Property in a List that is a property of the Part.
View
<DataGrid>
<DataGridTemplateColumn Header="Company">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox x:Name="CompanyEditComboBox"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.Companies}"
SelectedItem="{Binding Company, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectionChanged = "CompanyEditComboBox_SelectionChanged" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Company}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="CompanyType">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox x:Name="CompanyTypeEditComboBox"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.CompanyTypes}"
SelectedItem="{Binding IdentificationCompanyType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding IdentificationCompanyType, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid>
View Code-Behind
private void CompanyEditComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var vm = (PartViewModel)DataContext;
var box = (ComboBox) sender;
var c = (Company) box.SelectedItem;
vm.SetDefaultCompanyType(c);
}
ViewModel
public void SetDefaultCompanyType(Company c)
{
SelectedIdentification.IdentificationCompanyType = c.DefaultCompanyType;
OnPropertyChanged("IdentificationCompanyType");
}
Solved it. I had to add a
OnPropertyChanged("IdentificationCompanyType");
into the setter of the IdentificationCompanyType in the Identification class. After that it got automatically updated in the DataGrid.
Recently I asked similar questions here and here, but could not fix the issue properly.
I have a DataGrid with ComboBox that can contain either a selected item or not. But if it does then the ComboBox should select it when the dropdown is opening which is doesn't.
Currently I have this code which works except when opening the dropdown the first time. It is nothing selected.
<DataGridTemplateColumn Header="Company">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.Companies}"
SelectedItem="{Binding Company, Converter={StaticResource NullValueConverter}}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Company, Converter={StaticResource NullValueConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
The NullValueConverter prevents exceptions if the Company is null.
If your company was not a string as you mentioned in the comments then it can't display the Name unless you set
DisplayMemberPath="Name" or create an ItemTemplate.
You should use SelectedItem="{Binding
Company,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" to update
the value as soon as it changes because if you don't it will only
raise ProperyChanged when you focus another cell or row.
if your Property was immutable or a value type then you
should use SelectedValue="{Binding Path=Company,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" SelectedValuePath="Content"
.
I have this XAML that selects a value from a combobox that the ItemSource is a Enum. The tutorial I used is:
http://www.c-sharpcorner.com/uploadfile/dpatra/combobox-in-datagrid-in-wpf/
<DataGrid x:Name="dgProductItem"
ItemsSource="{Binding ProductVersion.ProductItems}"
<DataGridTemplateColumn Header="Deployment Type" Width="120">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding DeploymentType}"></TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Source={StaticResource DeploymentTypeEnum}}"
SelectedItem="{Binding DeploymentType}">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
However when I change a value from one row, it will update all the rows. Does anyone know why this is?
Edit:
if I just change one row, it will only update that row, but when I go to change a different row, that row I just changed will also change the previous one..
Cheers
Apologies for the duplicates but after a few hours of guessing because there isn't enough material on the web for this kinda stuff, the solution is:
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Source={StaticResource DeploymentTypeEnum}}"
SelectedItem="{Binding DeploymentType}"
**IsSynchronizedWithCurrentItem="false**">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
IsSynchronizedWithCurrentItem - does what it says on the tin. However, when you select an item, the current one will disappear but at least it won't update all rows.
I want to make my ComboBox editable. My Combobox displays a list of countries, and I would like my users to be able to type in the country to search for it. However, in its current state, it doesn't do that. What have I done wrong?
<ComboBox x:Name="CmbCountryList" Width="150"
IsEditable="True" IsTextSearchEnabled="True"
IsTextSearchCaseSensitive="False" StaysOpenOnEdit="True"
TextSearch.TextPath="CountryName"
ItemsSource="{Binding CountryMasterList, Mode=TwoWay}"
DisplayMemberPath="CountryName"
SelectedValuePath="CountryID"
SelectedItem="{Binding Path=CountryObj, Mode=TwoWay, ValidatesOnDataErrors=True}"
Text="{Binding Path=CountryName, Mode=TwoWay}"
IsSynchronizedWithCurrentItem="False" />
Check http://weblogs.asp.net/okloeten/archive/2007/11/12/5088649.aspx for an example of how you can implement this.