The tapped on comboBox work incorrectly - wpf

I have comboBox with names list . When I try to select a name in the list, it generally takes 3-5 clicks on the selected name.
<ComboBox
Grid.Row="6"
Height="50"
Margin="0,20,0,0"
Name="AssetClassComboBox"
HorizontalAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
ItemsSource="{x:Bind ListAssetClass, Mode=OneWay}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="models:ComboBoxAssetClassItem">
<ComboBoxItem Content="{x:Bind Name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
If I delete this code the comboBox works correctly, the list is visible, but I cannot see the names.
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="models:ComboBoxAssetClassItem">
<ComboBoxItem Content="{x:Bind Name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>

Instead of creating a ItemTemplate you could simply use the property DisplayMemberPath of ComboBox:
<ComboBox
...
DisplayMemberPath="Name"
ItemsSource="{x:Bind ListAssetClass, Mode=OneWay}">

Related

WPF ComboBox IsEnable when using custom DataTemplate

Here it's the following. I want to disable a combo box.
In some scenarios in a window I just set SelectedItem from ViewModel to something and don't allowing the user to change it. But in some cases I want to allow.
This one works perfectly when changing ComboBoxIsEnabled property in VM.
<ComboBox ItemsSource="{Binding MyColletionView, Mode=OneWay}"
SelectedItem="{Binding MySelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name"
IsEnabled="{Binding MyComboBoxIsEnabled}"/>
After changing ComboBox.ItemTemplate the IsEnable property not reacting anymore. In short, I can't disable the ComboBox.
<ComboBox ItemsSource="{Binding MyColletionView, Mode=OneWay}"
SelectedItem="{Binding MySelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding MyComboBoxIsEnabled}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource CustomerConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
I don't want to disable the ComboBoxItem, I want to disable the ComboBox itsef.
Any suggestions, or someone facing the same issue?
<ComboBox Height="20" Width="200" IsEnabled="True" Margin="38,38,1682,1022" ItemsSource="{Binding SourceData}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
I write a sample as you described.but I didnot use mvvm.I want to prove that there is no relationship in IsEnable and ItemTemplate.
you can trace this issue from tips as follow.
Watch Output window in VisualStudio.There may be some exception.
replace mvvm with codebehind and try.

How to do text search in DropDown of ComboBox with IsEditable=false

I have a ComboBox with IsEditable = false. When the user drops down the list, I'd like to support him in searching for the right item, by scrolling to the first item that fits to a letter the user types.
So when the DropDown is open and the user types 'S', I'd like him to scroll to the first item (in my case: customer) whose name starts with 'S'.
I can't use the built-in text search because the ComboBox's IsEditable is false. The user can only select one of the proposed values (customers).
How can I do text search anyway? Here is my code:
<ComboBox x:Name="cmbCustomer"
ItemsSource="{Binding LstAllCustomers, Mode=TwoWay}"
SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}"
ItemContainerStyle="{StaticResource customerListStyle}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="2" Text="{Binding ID}"/>
<TextBlock Margin="2" Text="{Binding LastName}"/>
<TextBlock Margin="2" Text="{Binding FirstName}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Set the IsTextSearchEnabled property to true and the TextSearch.TextPath attached property to either "LastName" or"FirstName" or whatever your property is called:
<ComboBox x:Name="cmbCustomer"
ItemsSource="{Binding LstAllCustomers, Mode=TwoWay}"
SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}"
ItemContainerStyle="{StaticResource customerListStyle}"
IsTextSearchEnabled="True" TextSearch.TextPath="LastName">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="2" Text="{Binding ID}"/>
<TextBlock Margin="2" Text="{Binding LastName}"/>
<TextBlock Margin="2" Text="{Binding FirstName}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
This should work even if you don't set the IsEnabled property to true, assuming that your Customer class actually has a LastName property.

how to bind the selected item from the combobox to textblock inside datagrid

I am having combobox inside datagrid which is inside cell editing template.
What i want is that when a user select an item from the combobox and move to the next cell, the selected item must bind to the textblock of that same cell.
if anyone knows how to do help me. here is my xaml
<DataGrid AutoGenerateColumns="False" VirtualizingStackPanel.IsVirtualizing="False"
Grid.Row="1" Grid.ColumnSpan="7" Name="attendancegrid" Background="#FFDCE8EB" CanUserAddRows="False"
BorderBrush="Chocolate" BorderThickness="5" RowHeight="30" IsSynchronizedWithCurrentItem="True"
HorizontalGridLinesBrush="#FFB74646" IsReadOnly="False" Foreground="Black" Loaded="attendancegrid_Loaded"
SelectionChanged="attendancegrid_SelectionChanged" CurrentCellChanged="attendancegrid_CurrentCellChanged"
CellEditEnding="attendancegrid_CellEditEnding">
<DataGridTemplateColumn Header="Monday" Width="100">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ComboBox x:Name="monday" Width="50" IsSynchronizedWithCurrentItem="true" Loaded="monday_Loaded" SelectionChanged="monday_SelectionChanged"></ComboBox>
<ComboBox x:Name="staff" Width="50" Loaded="staff_Loaded"></ComboBox>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel >
<TextBlock x:Name="mon"></TextBlock>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid>
You have to create one collection property to be bound on Combobox like
public List<string> MyCollection{get;set;}
and one string property for binding it to the SelectedItem of ComboBox and Your TextBlock like
private string _SelectedCollectionItem;
public string SelectedCollectionItem
{
get{return _SelectedCollectionItem;}
set{_SelectedCollectionItem=value;
RaisePropertyChanged("SelectedCollectionItem");}
}
now in your xaml do like this
DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ComboBox ItemsSource="{Binding MyCollection}" SelectedItem={Binding SelectedCollectionItem,Mode=TwoWay}></ComboBox>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel >
<TextBlock Text={Binding SelectedCollectionItem}></TextBlock>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>

ComboBox itemsSource and default selected value doesn't work

I have this code:
<ComboBox Name="cbxWorkers" HorizontalContentAlignment="Right"
ItemsSource="{Binding Workers}">
<ComboBoxItem IsSelected="True" Content="Select" />
<ComboBox.ItemTemplate>
<DataTemplate>
<ComboBoxItem Content="{Binding LastName}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Everything works fine except the second line.
It gives me a runtime exception:
Items collection must be empty before using ItemsSource.
How can I deal with that so I will get also all the Workers, and also the item - "Select" as the first item of the combobox?
Thanks a lot :)
You can't have two sources. You'd have to specify in code from the ItemsSource which item you want selected.
<ComboBox Name="cbxWorkers" HorizontalContentAlignment="Right" ItemsSource="{Binding Workers}">
<ComboBox.ItemTemplate>
<DataTemplate>
<ComboBoxItem Content="{Binding LastName}" IsSelected="{Binding isSelected}" />
</DataTemplate>
</ComboBox.ItemTemplate>
You can do this, or you can just make an extra first Item in C#/VB and make sure it's selected.
You can do this with a CompositeCollection:
<ComboBox x:Name="cbxWorkers" SelectedIndex="0">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=LastName}" />
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem Content="Select" />
<CollectionContainer Collection="{Binding Workers}" />
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
Note: you need to set the SelectedIndex="0" on the ComboBox, because when the ComboBoxItem is in the ItemsSource, its IsSelected property won't set the selection on the ComboBox.
Edit concerning CollectionContainer
As #H.B. pointed out, the Binding on CollectionContainer won't work this way. You have a couple of options. They are spelled out for you by this CodeProject article, so I won't repeat them here. The one method that doesn't mention is the newish (as of .NET 4) x:Reference option. It would be used like this:
<CollectionContainer Collection="{Binding DataContext.Workers, Source={x:Reference cbxWorkers}}" />

How to trigger DataGridevents DataGridBeginningEdit, DataGridCellEditEnding with a Combobox in Silverlight? / CellTemplate for a Combobox

I want to use the DataGridevents (DataGridBeginningEdit, DataGridCellEditEnding, ..etc) to handle and detect changes. As far as I understood, without a "CellTemplate" these are not triggered. So I am trying to create an appropriate celltemplate using a TextBlock, but I guess it is not very straightforward with the binding I am using for the Combobox in the CellEditingTemplate, because I am using "DisplayMemberPath"..
There are examples of simpler cases but I couldn't find smth for this scenario. See Xaml snippet below;
<data:DataGridTemplateColumn Width="100">
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Center" />
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
<data:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox HorizontalAlignment="Stretch"
ItemsSource="{Binding DurationTypeList, Source={StaticResource itemSourceProvider}}"
SelectedValuePath="Code"
SelectedValue="{Binding Path=DurationTypeCode, Mode=TwoWay}"
DisplayMemberPath="Template" />
</DataTemplate>
</data:DataGridTemplateColumn.CellEditingTemplate>
</data:DataGridTemplateColumn>
Thank you
It turns out, i have two options..
Solution #1
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Left" Text="{Binding Path=DurationType.Template, Mode=OneWay}" />
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
<data:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox HorizontalAlignment="Stretch"
ItemsSource="{Binding DurationTypeList, Source={StaticResource itemSourceProvider}}"
SelectedValuePath="Code"
SelectedValue="{Binding Path=DurationType, Mode=TwoWay}"
DisplayMemberPath="Template" />
</DataTemplate>
</data:DataGridTemplateColumn.CellEditingTemplate>
I changed the binding path from string to the object with Code and Template properties..
This blog helped a lot..

Resources