Selecteditem on combobox null reference exception - wpf

I want to use SelectedItem to set selection to a combobox from code.
I can only get it to work by using SelectedValue. SelectedItem will throw a null reference exception with this at the top of the stacktrace:
at AttachedCommandBehavior.CommandBehaviorBinding.Execute()
The XAML:
<Window x:Class="MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:acb="clr-namespace:AttachedCommandBehavior;assembly=AttachedCommandBehavior"
Title="Window1" Height="300" Width="300">
<StackPanel>
<ComboBox Name="ComboItems1"
DisplayMemberPath="Value"
SelectedValuePath="Key"
ItemsSource="{Binding Items}"
SelectedValue="{Binding SelectedValue}"
acb:CommandBehavior.Event="SelectionChanged"
acb:CommandBehavior.Command="{Binding Path=SelectionChangedCommand}"
acb:CommandBehavior.CommandParameter="{Binding ElementName=ComboItems1, Path=SelectedItem}" />
<ComboBox Name="ComboItems2"
DisplayMemberPath="Value"
SelectedValuePath="Key"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}"
acb:CommandBehavior.Event="SelectionChanged"
acb:CommandBehavior.Command="{Binding Path=SelectionChangedCommand}"
acb:CommandBehavior.CommandParameter="{Binding ElementName=ComboItems2, Path=SelectedItem}"/>
</StackPanel>
The code:
Imports AttachedCommandBehavior
Public Class MainWindowViewModel
Private _mainWindowView As MainWindowView
Public Property Items As New List(Of KeyValuePair(Of Integer, String))
Public Property SelectedItem As Nullable(Of KeyValuePair(Of Integer, String))
Public Property SelectedValue As Nullable(Of Integer)
Public Property SelectionChangedCommand As ICommand
Public Sub New()
Items.Add(New KeyValuePair(Of Integer, String)(1, "first item"))
Items.Add(New KeyValuePair(Of Integer, String)(2, "second item"))
Items.Add(New KeyValuePair(Of Integer, String)(3, "third item"))
Dim simpleCommand As SimpleCommand = New SimpleCommand()
simpleCommand.ExecuteDelegate = Sub(selectedItem As Object)
HandleSelectionChanged(selectedItem)
End Sub
SelectionChangedCommand = simpleCommand
SelectedValue = 1
'SelectedItem = Items(1) 'uncomment this to raise the null ref exception
End Sub
Private Sub HandleSelectionChanged(ByRef selectedItem As Object)
If selectedItem IsNot Nothing Then
'Do something
End If
End Sub
End Class
Why does selecteditem not work?
UPDATE:
Nikolay: you have a keen eye. That was due to last minute copy paste work!
Blindmeis: this, ofcourse, is an abstract from a much larger program in which I need the selectionchanged event to execute some actions. Those commandbindings have to stay (though maybe they need some fixing).
Regards,
Michel

why you have these commandbindings?
<ComboBox
DisplayMemberPath="Value"
SelectedValuePath="Key"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}" />
viewmodel
//this select the "third item" in your combobox
SelectedItem = Items[2];/dont know the vb indexer stuff ;)
this works.
Edit:
viewmodel
public KeyValuePair<int, string> SelectedItem
{
get{return this._selectedItem;}
set{
if(this._selectedItem==value)
return;//no selection change
//if you got here then there was a selection change
this._selectedItem=value;
this.OnPropertyChanged("SelectedItem");
//do all action you want here
//and you do not need selection changed event commmandbinding stuff
}
}

acb:CommandBehavior.CommandParameter="{Binding ElementName=ComboItems, Path=SelectedItem}"
You don't have element with name ComboItems, you have ComboItems1 and ComboItems2. I think this is the problem.

Related

Binding to DataContext Failing

I have a wpf window that displays tasks. The user clicks on a task in a TreeView control then other controls (TextBox, ComboBox, etc.) shows the various properties of the selected task. I have implemented this as follows:
1) The TreeView is pupulated by:
ItemsSource="{Binding Source={StaticResource cvsTasks}}"
2) The DataContext for the window is set in code-behind as follows:
Public Class Tasks
Private tsk As Task
....
Private Sub LoadMe(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
DataContext = tsk
....
End Sub
Private Sub SelectTask(sender As Object, e As RoutedPropertyChangedEventArgs(Of Object)) Handles treTasks.SelectedItemChanged
tsk = DirectCast(e.NewValue, Task)
End Sub
....
End Class
3) Each of the task properties use binding as shown below for the Description property:
<TextBox
x:Name="txtDescription"
AcceptsReturn="True"
Text="{Binding Path=Description}">
</TextBox>
and that is what is not working. None of the controls with binding show corresponding value when a TreeView item is selected by the user.
What an I doing wrong?
Setting the private tsk field won't cause the view to refresh. Try to set the DataContext property in your event handler:
Private Sub SelectTask(sender As Object, e As RoutedPropertyChangedEventArgs(Of Object)) Handles treTasks.SelectedItemChanged
DataContext = DirectCast(e.NewValue, Task)
End Sub
Or make tsk a public property that you bind to and raise the PropertyChanged event for. This requires you to implement the INotifyPropertyChanged interface.
Please add Mode and UpdateSourceTrigger in your XAML.
Text="{Binding Path=Description, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
You can achieve this using ElementName.
Consider this is your TreeView control
<TreeView x:Name="myTreeView" ItemsSource="{Binding Source={StaticResource cvsTasks}}">
...
</TreeView>
Then, binding at your TextBox will be like,
<TextBox Text="{Binding ElementName=myTreeView, Path=SelectedItem.Description, Mode=TwoWay}"
AcceptsReturn="True"/>

ViewModel does not update Combobox SelectedValue

I've got a problem with a Combobox in a VSIX-Project. I'm using the MVVM-pattern.
<ComboBox
ItemsSource="{Binding ProjectList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name"
IsSynchronizedWithCurrentItem="True"
Style="{StaticResource MyStyle}"
SelectedValue="{Binding Project, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
This is my Combobox which is bindet to a List of Projects. The SelectedValue is a project of the list. Like this:
ProjectList = New List(Of Project)(Helper.GetFormsProjects())
If ProjectList.Count > 0 Then
Project = ProjectList(0)
End If
But if I select another Value in the Combobox, it wouldn't call the setter of the project property.
Here are the properties:
Public Property _projectList As List(Of Project)
Public Property ProjectList As List(Of Project)
Get
Return _projectList
End Get
Set(value As List(Of Project))
_projectList = value
OnPropertyChanged()
End Set
End Property
Public Property _project As Project
Public Property Project As Project
Get
Return _project
End Get
Set(value As Project)
_project = value
OnPropertyChanged()
End Set
End Property

Binding list to Dropdown in SIlverlight not working

I am using Silverlight Application in that I am using Datagrid and binding Data based on Observable Collection, but when I am trying to Bind the Observable Collection to Dropdown it's not binding, do we need to write code to Bind in the xaml Code behind.
My Code :
<sdk:DataGridTemplateColumn Header="lab Validated?" CanUserSort="True">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ComboBox Height="Auto" HorizontalAlignment="Left"
Name="cboLabValidated" VerticalAlignment="Center" Width="80"
ItemsSource="{Binding Path=LabValidatedList}">
</ComboBox>
</Grid>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
ViewModel :
Public LabValidatedList As New List(Of String)() From { _
"Yes", _
"No"
}
In order to be usable as the source of a binding, LabValidatedList has to be a public property, not a field:
Private labValidatedListValue As New List(Of String)() From { _
"Yes", _
"No"
}
Public Property LabValidatedList() As List(Of String)
Get
Return Me.labValidatedListValue
End Get
Set(ByVal value As List(Of String))
Me.labValidatedListValue = value
End Set
End Property
Sorry if the above does not compile immediately, but VB is not my language. Note also that a List(Ofd String) is not an ObservableCollection.

Treeview events with Attached Command Behavior

I want to handle events on a treeview with ACB (http://marlongrech.wordpress.com/2008/12/04/attachedcommandbehavior-aka-acb/).
I am stuck with the bindings in the XAML file. The event is fired but I keep getting null reference exceptions in the ACB library because strategy is null:
/// <summary>
/// Executes the strategy
/// </summary>
public void Execute()
{
strategy.Execute(CommandParameter);
}
In the XAML file I added the following (excerpt):
xmlns:acb="clr-namespace:AttachedCommandBehavior;assembly=AttachedCommandBehavior"
<StackPanel x:Name="VerklaringenTreeviewPanel">
<Border x:Name="TreeviewHeaderBorder" Style="{StaticResource TreeviewBorderHeaderStyle}">
<TextBlock x:Name="tbTreeviewHeader" Text="Verklaringen concept" Style="{StaticResource TreeviewHeaderStyle}"/>
</Border>
<TreeView x:Name="MyTreeview" ItemsSource="{Binding}" Style="{StaticResource TreeviewStyle}">
<TreeView.Resources>
<ResourceDictionary Source="..\Themes\TreeviewItemStyle.xaml" />
</TreeView.Resources>
</TreeView>
<StackPanel.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:MyDataType}" ItemsSource="{Binding MyChildDataType}">
<StackPanel Orientation="Horizontal" acb:CommandBehavior.Event="MouseDown" acb:CommandBehavior.Command="{Binding SomeCommand}" acb:CommandBehavior.CommandParameter="Hi There">
And in the Viewmodel I added:
Public Property SomeCommand() As ICommand
Get
Return _someCommand
End Get
Private Set(value As ICommand)
_someCommand = value
End Set
End Property
Public Sub New()
MyBase.New()
Dim simpleCommand As SimpleCommand = New SimpleCommand()
simpleCommand.ExecuteDelegate = Sub(x As Object)
Dim test As String
test= "noot" 'I want to hit this breakpoint
End Sub
Me.SomeCommand = simpleCommand
End Sub
Who can help me out with the binding?
Regards,
Michel
The not too descriptive exception is throw because this binding is broken: acb:CommandBehavior.Command="{Binding SomeCommand}".
So WPF could not find your SomeCommand property. I guess the problem is around the HierarchicalDataTemplate so the DataContextis not what you would expect...
Check for binding errors in the Visual Studio's Output window during runtime and you will know what to fix then it should work.

wpf two way binding not working

i have
<Grid Name="thisPage">
<TextBlock Name="tbtb" />
<ScrollViewer Name="sv4" Visibility="Hidden">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextChanged="TextBox_TextChanged"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
in the MainWindow.vb, i have
movieArray as ObservableCollection(of Movie)
For i As Integer = 0 To 5
Me.movieArray.Add(New Movie(i))
Next
Me.sv4.DataContext = Me.movieArray
Me.listBox5.DataContext = Me.movieArray
Private Sub TextBox_TextChanged(sender As System.Object, e As System.Windows.Controls.TextChangedEventArgs)
Me.tbtb.Text = ""
For Each m As Movie In movieArray
Me.tbtb.Text += p.Title.ToString + " ^ "
Next
End Sub
Class Movie
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler _
Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(ByVal info As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
End Sub
Property Title As Integer
Get
Return Me._title
End Get
Set(value As Integer)
Me._title = value
If Not (value = _title) Then
Me._title= value
NotifyPropertyChanged("Title")
End If
End Set
End Property
for the next page i have,
<Grid Name="nextPage" Visibility="Hidden" >
<ListBox Name="listBox5" >
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ListBox>
</Grid >
To change pages i just toggle the visibility of thisPage and nextPage using back, next buttons.
IM not sure what im doing wrong as:-
listbox5 shows only the original values, not anything changed by
textboxes.
tbtb, however is able to update its values
I think the problem might be your 'Title' property setter.
I'm a C# guy, not a VB expert... but it would appear that NotifyPropertyChanged will never get called.
value = _title will always be true because you just set Me._title = value in the previous line of code. Thus you will never execute any of the code in your if statement.
Why are you using Textchanged evetn in two way binding you dont need kind of stuff. two way binding is directly bind values from your view to property and from property to view
so don't use textchanged event and try again. this will work.

Resources