WPF: ComboBox with selecteditem set make not use of SelectedIndex=0? - wpf

Why is the first element in my combobox popup menu not shown in the selected item area of
my combobox , when I use the SelectedItem binding? Without that it is showing up ?? Using
the same code selecteditem + selectedindex that is no problem!
<ComboBox
ItemsSource="{Binding SchoolclassSubjectViewModels}"
SelectedItem="{Binding SelectedSchoolclassSubjectViewModel}"
SelectedIndex="0"
Height="23"
HorizontalAlignment="Left"
Margin="375,13,0,0"
VerticalAlignment="Top"
Width="151">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SchoolclassName}" />
<TextBlock Text=" " />
<TextBlock Text="{Binding SubjectName}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Well as workaround I used:
SchoolclassSubjectViewModels.Add(schoolclassSubjectVM);
SelectedSchoolclassSubjectViewModel = schoolclassSubjectVM;
and this:
SelectedItem="{Binding SelectedSchoolclassSubjectViewModel,Mode=TwoWay}"
but I would prefer the xaml only way as it should really work.

It is because the reference inside your ItemsSource collection is not the same as the one in your SelectedItem property. I would venture to guess that you are using one object context to query your database for the list of SchoolclassSubject objects which the ItemsSource is bound to, but another context to query the actual data item to which you bind the SelectedItem. Even though the list contains a reference which represents the value held by your object, it is not really the same reference, but a separate instance of the same data.
There are ways to solve this issue, most of them involve using the SelectedValuePath and SelectedValue instead of the SelectedItem properties, but the concrete solution would be different depending on your particular ORM.

Related

how to disable a checkbox in a listbox wpf

I have a ListBox with a DataTemplate like this:
<ListBox ItemsSource="{Binding Reportes,Mode=TwoWay}" >
<ListBox.ItemTemplate>
<DataTemplate >
<StackPanel IsEnabled="{Binding PantallaActiva}">
<CheckBox FontWeight="Bold" HorizontalAlignment="Left"
Content="{Binding NORepo,Mode=TwoWay }"
IsChecked="{Binding Path=EmitirReporte,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock FontSize="9" Foreground="Gray" TextWrapping="Wrap" Text="{Binding DSRepo,Mode=TwoWay}" MaxWidth="140" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The property "PantallaActiva" is a true/false property in my ViewModel that is set to False when some process starts. I need to disable the checkBoxes when that process starts. My problem is that never happens the checkboxes or the stack panel ,can`t see the PantallaActiva property or any other property in my viewModel, they only see the properties in the items collection Reportes[i] and that's, I guess, my problem, so how do I have to do the binding ?
thanks in advance
If I understand your question correctly, the PantallaActiva property isn't part of your Reporte class (the elements in your collection). It's probably a property on your view model instead, right?
The scope of your ItemTemplate is bound to the type Reporte since you bound that collection as the ItemsSource. That's why XAML binding cannot find the property on that type. You need to bind the IsEnabled property to the property on your ViewModel.
<CheckBox IsEnabled="{Binding Path=DataContext.PantallaActiva, RelativeSource={RelativeSource AncestorType=MyControlType}}" .../>
For this to work, you need to set MyControlType to an element up your visual tree whose DataContext is bound to your view model. (probably the parent of your ListBox)
It would be helpful to see the code in your view model.
replace with this. You only need to assign value as false, as by default, it was true.
IsChecked="{Binding Path=EmitirReporte,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,Value=False}"/>

Two way binding in ListBox ItemTemplate

I have a ListBox which DataTemplate is TextBox that can be edited. Where should I set Binding TwoWay? In ItemSource or In TextBox binding? Maybe in both? And how it works inside? Is it inherited? So if I set Binding in ItemSource - is it inherited in TextBox?
<ListBox HorizontalAlignment="Left" ItemsSource="{Binding Commands, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Two way binding should be setup op your item you need to display, in this case the Textbox. Here you need to have coupling back to your datacontext. You might want to consider setting the UpdateSourceTrigger property to PropertChanged.
This way you will always have entered value of your text, even without loosing focus.
The itemsource should not be Two way. One way will do since you probable will be binding to an observable collection. This will only be set once from your datacontext. This will automatically handle the adding and removing of items to your collection.
I'd add your code like this:
<ListBox Margin="10,0,0,0" Width="200" HorizontalAlignment="Left" ItemsSource="{Binding Commands}" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Where should I set Binding TwoWay?
You should set this Mode for TextBox like this:
<TextBox Text="{Binding Path=Name, Mode=TwoWay}" />
If I'm not mistaken, the Text property is listed TwoWay mode by default. Therefore, it's construction is not required.
From MSDN:
When used in data-binding scenarios, this property uses the default update behavior of UpdateSourceTrigger.LostFocus.
This means that updates the properties were visible at once, you need to set the property UpdateSourceTrigger to PropertyChanged:
<TextBox Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
So if I set Binding in ItemSource - is it inherited in TextBox?
No, inheritance will not be, because settings of Binding unique for each dependency property. Inheritance happens when using DataContext, but again, settings unique for each property.

Weird databinding issues in wpf combobox

I am writing what is turning out to be a simple GUI in WPF. At the moment I have a static list inside of a ComboBox, like this:
<ComboBox HorizontalAlignment="Left" Height="22" Margin="24,97,0,0" VerticalAlignment="Top" Width="83"
SelectedItem="{Binding fruit, Mode=TwoWay}">
<ComboBoxItem>apple</ComboBoxItem>
<ComboBoxItem>orange</ComboBoxItem>
<ComboBoxItem>grape</ComboBoxItem>
<ComboBoxItem>banana</ComboBoxItem>
</ComboBox>
I'm binding the SelectedItem to a singleton in my code that has already been initialized and used elsewhere.
I put a breakpoint on the get of fruit and it returns "grape", but the selected item is always blank. I even added a button so that I could call RaisePropertyChanged manually, but the RaisePropertyChange call didn't do anything either.
Finally, MVVMLight gives blendability. For no important reason I changed the binding in the combobox from SelectedItem to Text As soon as I did that, my design time form filled in with the expected values, but, when the code is running, the box continues to sit at the empty state
This is because you have items of type ComboBoxItem in the ComboBox but the property you are trying to bind to is of type string.
You have three options:
1.Instead of adding ComboBoxItem items add String items:
<ComboBox HorizontalAlignment="Left" Height="22" Margin="24,97,0,0" VerticalAlignment="Top" Width="83"
SelectedItem="{Binding fruit, Mode=TwoWay}">
<sys:String>apple</sys:String>
<sys:String>orange</sys:String>
<sys:String>grape</sys:String>
<sys:String>banana</sys:String>
</ComboBox>
2.Instead of SelectedItem bind to SelectedValue and specify SelectedValuePath as Content:
<ComboBox HorizontalAlignment="Left" Height="22" Margin="24,97,0,0" VerticalAlignment="Top" Width="83"
SelectedValue="{Binding fruit, Mode=TwoWay}"
SelectedValuePath="Content">
<ComboBoxItem>apple</ComboBoxItem>
<ComboBoxItem>orange</ComboBoxItem>
<ComboBoxItem>grape</ComboBoxItem>
<ComboBoxItem>banana</ComboBoxItem>
</ComboBox>
3.Do not specify items directly in XAML, but use ItemsSource property to bind to a collection of strings:
<ComboBox HorizontalAlignment="Left" Height="22" Margin="24,97,0,0" VerticalAlignment="Top" Width="83"
ItemsSource="{Binding Fruits}"
SelectedItem="{Binding fruit, Mode=TwoWay}"/>
You should bind ComboBox.ItemSource to a list of strings (make the List of strings an ObservableCollection<string> in case you add items to this list) and then set the fruit variable to an instance in the List of strings.
I think you have your problem because your fruit variable references a different instance than you have in your list of ComboBoxItems. (even though the strings are the same)

Bind WPF DataGrid column to another

I want to enable / disable a DataGridTextColumn based on whether or not the SelectedValue of its neighboring DataGridComboBoxColumn == 'Other'
I can make this work in a ListBox as below, but this won't work in my DataGrid environment as the DataGridComboBox column doesn't have a name property.
<ListBox Grid.Row="1" Grid.Column="1" ItemsSource="{Binding Source={StaticResource CustomData}}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ComboBox Name="operatorComboBox" SelectedValue="{Binding OperatorId}" ItemsSource="{Binding Source={StaticResource Operator}}" SelectedValuePath="Id" DisplayMemberPath="Name"></ComboBox>
<TextBox Text="{Binding Name}" Visibility="{Binding Path=SelectedValue, ElementName=operatorComboBox, Converter={StaticResource intToVis}}"></TextBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
So can this be done with a DataGrid?
(I know I've changed visibility in the ListBox example, but its not a quantum leap to change that to enabled. (Obviously hiding an entire column would be a bad thing in a proper DataGrid)
this question is fairly similar to what I'm asking, I just can't seam to mangle the solution into what I'm after
The easiest way I can think of solving this problem is actually to create a DataGridTemplateColumn instead of a DataGridTextBoxColumn then create a textbox inside the template. In order to disable / enable the textbox, bind the IsEnabled property to the underlying OperatorId property. You will also have to write a ValueConverter that checks whether the OperatorId value == 'Other' and returns that value.

WPF 2 ComboBox binding problem

I have the following problem:
there is a class with a couple of string properties
there is a collection of such class entities
That collection is shown in tree on the left of some windows and details shown on the right. I'm binding string properties of selected node to comboboxes in details.
First combobox always have the same ItemsSource but the second one ItemsSource depends on SelectedItem of the first combo...
<ComboBox
Grid.Column="1"
SelectedIndex="0"
x:Name="cbClass"
Style="{DynamicResource ComboBoxValidationError}"
SelectedValue="{Binding Path=Description.Node.ClassName, ElementName=userControl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={StaticResource classesProvider}}"
Width="Auto"
Height="Auto"
DisplayMemberPath="Description"
SelectedValuePath="FQN" />
<ComboBox
Grid.Column="1"
SelectedIndex="0"
Grid.Row="1"
x:Name="cbMethod"
SelectedValue="{Binding Path=Description.Node.MethodName, ElementName=userControl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,diag:PresentationTraceSources.TraceLevel=High}"
ItemsSource="{Binding Path=SelectedItem.Methods, ElementName=cbClass, Mode=Default,diag:PresentationTraceSources.TraceLevel=High}"
Style="{DynamicResource ComboBoxValidationError}"
Width="Auto"
Height="Auto"
SelectedValuePath="Name"
DisplayMemberPath="Description" />
Now when i create new node in the tree, both string properties have null reference. And when first combo changes its SelectedItem for the NEW node, second ComboBox binds null to the string value of the OLD node, which were selected before creating new node in the tree... I wonder what should i do in this case?
I've just found an answer.
Binding are notified in the order of their declaration, WPF is not going to analyse dependencies of bindings :)
So swapping declarations of ComboBoxes solves the problem... It's acceptable in this scenario because I place these ComboBoxes in Grid manually setting their Grid.Row and Grid.Column...
Though solution is not very pleasing, it works!

Resources