问题
I have 2 comboboxes. If i select a Activity in the 1st one, the related sub activities should be displayed in the second combobox. The code looks fine as per MVVM style but when i select an activity on 1st one, the related subactivities in the 2nd combobox are not synched. Here is my code: View
<Window x:Class="TestDGCombosBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestDGCombosBinding"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<ObjectDataProvider x:Key="ActivitiesDataProvider" ObjectType="{x:Type local:Activities}" MethodName="GetActivities"/>
<local:DebugConverter x:Key="DebugConverter" />
</Grid.Resources>
<DataGrid
Grid.Row="1" Grid.Column="1"
AutoGenerateColumns="False"
SelectionUnit="CellOrRowHeader"
SelectionMode="Single"
IsSynchronizedWithCurrentItem="True"
RowBackground="White"
AlternatingRowBackground="LightGray"
AlternationCount="2" Name="dataGrid1" CurrentCellChanged="dataGrid1_CurrentCellChanged">
<DataGrid.BindingGroup>
<BindingGroup />
</DataGrid.BindingGroup>
<DataGrid.Resources>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Activities Custom" CanUserSort="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Text="{Binding CurrentActivity}"
SelectedValuePath="ActivityID"
DisplayMemberPath="ActivityName"
ItemsSource="{Binding Source={StaticResource ActivitiesDataProvider}}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="SubActivities Custom" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Text="{Binding CurrentSubActivity}"
SelectedValuePath="SubActivityID"
DisplayMemberPath="SubActivityname"
ItemsSource="{Binding Path=SubActivitiesOfCurrentActivity}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
Model
public class Activities
{
public DataView GetActivities()
{
return ActivitiesAccess.GetAllActivities();
}
}
ViewModel
public class ActivitiesViewModel : INotifyPropertyChanged
{
public ActivitiesViewModel()
{ }
private int currentActivity;
public int CurrentActivity
{
get { return currentActivity; }
set {
currentActivity = value;
SubActivitiesOfCurrentActivity = ActivitiesAccess.GetAllSubActivitiesinActivity(currentActivity);
OnPropertyChanged("CurrentActivity");
}
}
private DataView subActivitiesOfCurrentActivity;
public DataView SubActivitiesOfCurrentActivity
{
get {return subActivitiesOfCurrentActivity; }
set
{
subActivitiesOfCurrentActivity = value;
OnPropertyChanged("SubActivitiesOfCurrentActivity");
}
}
private int currentSubActivity;
public int CurrentSubActivity
{
get { return currentSubActivity; }
set
{
currentSubActivity = value;
OnPropertyChanged("CurrentSubActivity");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
When i debug the code when i select an activity from the 1st drop down, the CurrentActivity property value is always 0 which im not sure why. This value should be equal to the ActivityID of the selected activity. I searched alot to get help but i couldnt find anything. I will be very happy if someone could specify any problem in the code.
回答1:
Don't bind to the Text property in your comboboxes, try replacing:
<ComboBox Text="{Binding CurrentActivity}"
SelectedValuePath="ActivityID"
DisplayMemberPath="ActivityName"
ItemsSource="{Binding Source={StaticResource ActivitiesDataProvider}}"/>
with:
<ComboBox ItemsSource="{Binding Source={StaticResource ActivitiesDataProvider}}"
SelectedValuePath="ActivityID"
DisplayMemberPath="ActivityName"
SelectedValue="{Binding CurrentActivity}"
IsSynchronizedWithCurrentItem="True"/>
Same idea for the sub activities combobox. In general, for comboboxes use the SelectedItem and SelectedIndex properties. Also use IsSynchronizedWithCurrentItem (depending on the type of ItemsSource.
By the way, you don't need to bind to the ID if you don't want to, you can bind directly to the whole object by using:
SelectedValue="{Binding SelectedItem}"
which will bind the value of the combobox to the selected item of the list, just keep it in synch with your VM using IsSynchronizedWithCurrentItem="True" (this applies if your VM is managing the list and knows which the selected item is).
Hope this helps you! Regards
回答2:
I resolved my issue. When An Activity is Changed, the related Sub-Activities should be notified of the change. But when the Sub-Activity is changed there is no need to notify the Activity.
I just commented OnPropertyChanged() call in CurrentSubActivity property. Here is the code
private int currentSubActivity;
public int CurrentSubActivity
{
get { return currentSubActivity; }
set
{
//OnPropertyChanged("CurrentSubActivity");
this.currentSubActivity = value;
}
}
I hope this helps someone out there too :)
来源:https://stackoverflow.com/questions/14651098/databinding-2-comboboxes-issue