Editing
I have two objects named Racers and Divisions. One racer can be in zero or more divisions and one division can contain zero or more racers. I'm editing the relationship on a Racer maintenance form where a racer's divisions are selected in a checkbox list. See the previous post for details.View Model
To accommodate this I have two commands in my Maintain Racer view model, one for adding a division and one for removing a division. And a keep the original list of racer divisions in case the user cancels. Here are the relevant parts of the view model:
private List<Division> _originalRacerDivisions;
public ICommand AddDivisionCommand { get; set; }
public ICommand RemoveDivisionCommand { get; set; }
// Constructor
public RacerDetailViewModel(IDerbyDataService derbyDataService)
{
... snip ...
AddDivisionCommand = new CustomCommand(AddDivision, CanAddRemoveDivision);
RemoveDivisionCommand = new CustomCommand(RemoveDivision, CanAddRemoveDivision);
... snip ...
}
private void LoadRacer(Racer racer)
{
... snip ...
_originalRacerDivisions = racer.Divisions;
... snip ...
}
private void AddDivision(object obj)
{
if (!(obj is Division))
throw new ArgumentException("Invalid division");
var divisionToAdd = (Division)obj;
var racerDivisions = RacerDivisions;
racerDivisions.Add(divisionToAdd);
RacerDivisions = racerDivisions;
}
private void RemoveDivision(object obj)
{
if (!(obj is Division))
throw new ArgumentException("Invalid division");
var divisionToRemove = (Division)obj;
var racerDivisions = RacerDivisions;
racerDivisions.Remove(divisionToRemove);
RacerDivisions = racerDivisions;
}
private bool CanAddRemoveDivision(object obj)
{
return true;
}
}
}
View
In the view I have a template column with a checkbox. I used this instead of a checkbox column because a checkbox column requires two clicks- one to select the row and a second to change the value. This way only one click is needed.
There are two triggers- one handles the Checked event and calls the AddDivision command, and the other handles the Unchecked event and called RemoveDivision command.
There are two triggers- one handles the Checked event and calls the AddDivision command, and the other handles the Unchecked event and called RemoveDivision command.
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<CheckBox VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5">
<CheckBox.IsChecked>
<MultiBinding Converter="{StaticResource localDivisionToBooleanConverter}"
Mode="OneWay">
<Binding Path="."></Binding>
<Binding Path="DataContext.RacerDivisions"
RelativeSource="{RelativeSource AncestorType=Window}"></Binding>
</MultiBinding>
</CheckBox.IsChecked>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding DataContext.AddDivisionCommand, RelativeSource={RelativeSource AncestorType=Window}}"
CommandParameter="{Binding Path=.}" />
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<i:InvokeCommandAction Command="{Binding DataContext.RemoveDivisionCommand, RelativeSource={RelativeSource AncestorType=Window}}"
CommandParameter="{Binding Path=.}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Cancelling
If the user decides to cancel, the racer's divisions need to be set back to their original values:private void CancelRacer(object obj)
{
racer.Divisions = _originalRacerDivisions;
... snip ...
}
No comments:
Post a Comment