Silverlight TreeView: MVVM and editing [5 – Add]

by Andrej Tozon 28. January 2009 16:59

In the previous post, we enabled editing for our TreeView. The last operation we need to implement is adding a new item to the hierarchy. With our tree item editor in place, there’s not so much left to do…

The only change we need to make with the View is add an Add button, right next to the Edit button. We’ll wire it to the Add command, which already exists.

The next stop is the ViewModel. We need to change the existing OnAddTopicExecuted handler to add a new child to the HelpTopic, passed into the method through CommandParameter:

private void OnAddTopicExecuted(object sender, ExecutedEventArgs e)
{
    HelpTopic topic = new HelpTopic();
    HelpTopic parent = e.Parameter as HelpTopic;
    if (parent == null)
    {
        HelpTopics.Add(topic);
    }
    else
    {
        parent.SubTopics.Add(topic);
    }
    topic.BeginEdit();
}

Note: when CommandParameter is not set to a valid HelpTopic (when it’s null), we’re adding a child to the root.

There is something wrong with the code above. I’m assuming that the SubTopics collection was already initialized when I created a new HelpTopic class instance. I this case, I assumed wrong and the above code would throw a nasty error.

I need to assure that SubTopics property is never null as this puts the HelpTopic in an invalid state. I’ll do that by inserting the collection initialization code in its constructor:

public HelpTopic()
{
    SubTopics = new ObservableCollection<HelpTopic>();
}

Better. But we’re not done yet. There is no way for user to cancel the newly added item. Sure, she can press the Cancel button when editing, but the node will not be removed from the tree.

This is the time to provide the HelpTopic class with an unique identificator field. When working with the database, the type of this field would align with whatever your database table primary key type is. For simplicity, I’ll use Guids here, just because their generation results in more unique results than a number randomization would.

The logic behind is this: when a new HelpTopic is being added, its Id is set to null. If the item is confirmed, the new Id is set, otherwise the item is removed from the hierarchy. Here’s how modified OnEndEditTopic and OnCancelEditTopic now look like:

private void OnEndEditTopic(object sender, ExecutedEventArgs e)
{
    HelpTopic topic = e.Parameter as HelpTopic;
    if (!topic.Id.HasValue)
    {
        topic.Id = Guid.NewGuid();
    }
    topic.EndEdit();
}

private void OnCancelEditTopic(object sender, ExecutedEventArgs e)
{
    HelpTopic topic = e.Parameter as HelpTopic;
    if (!topic.Id.HasValue)
    {
        topic.RemoveFromStructure(HelpTopics, item => { return item.SubTopics; });
    }
    topic.CancelEdit();
}

Wait! Before we end this, let me just put another button in a TreeView to enable user to add a new HelpTopic to the root of the tree. This is the modified template with a new button in place (added lines in bold italic):

<ControlTemplate TargetType="slt:TreeView">
    <Grid x:Name="Root" >
        <Grid.Resources>
            <SolidColorBrush x:Key="BorderBrush" Color="#FF000000" />
        </Grid.Resources>
        <Border x:Name="Border" BorderBrush="{StaticResource BorderBrush}" 
            BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"> <Border Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" Margin="1"> <ScrollViewer x:Name="ScrollViewer" HorizontalScrollBarVisibility="Auto"
                    VerticalScrollBarVisibility="Auto" Background="{x:Null}" BorderBrush="Transparent"
                    BorderThickness="0" IsTabStop="False" TabNavigation="Once"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Button HorizontalAlignment="Left" ToolTipService.ToolTip="Add Topic" input:CommandService.Command="AddTopic"> <Image Source="/EditableTreeView;component/Resources/add.png" Stretch="None" /> </Button> <ItemsPresenter x:Name="TreeItems" Grid.Row="1" Margin="5" /> </Grid> </ScrollViewer> </Border> </Border> </Grid> </ControlTemplate>

Editable TreeView

OK, we’ve got our TreeView to allow basic inline editing now, but not in very realistic scenario and it lacks usability. I’m going to end this series with this post and spin off to more general topics posts, covering more MVVM, LOB scenarios and Silverlight in general. A taste of things to come: improving, extending and expanding on the current state of this sample, going over the wire, testing and user experience.

The source code for this sample is available:

Tags:

Development | Layout | MVVM | Silverlight | Software | User Experience

Comments

1/28/2009 9:54:49 PM #

trackback

Trackback from Community Blogs

Silverlight Cream for January 28, 2009 -- #500

Community Blogs | Reply

1/29/2009 6:16:37 AM #

trackback

Trackback from DotNetShoutout

Andrej Tozon's blog | Silverlight TreeView: MVVM and editing [5 – Add]

DotNetShoutout | Reply

4/16/2009 8:26:19 PM #

Pankaj

Tried your example and work like charm...All series of TreeView: MVVM and editing is excellent...

Pankaj India | Reply

5/8/2009 8:11:55 AM #

Ed

I'm trying to modify your code to read/write from/to SQL Server DB. The point is that I'm having some problems because of the Async way of WCF services. Do you know any way to stop your "OnEndEditTopic" while the service is updating the DB?
The problem appears when the user add one childnode to the node just created and the service hasn't finished updating the DB.
Thank you.

Ed | Reply

5/8/2009 3:40:23 PM #

Andrej

Ed, you could move the logic from the OnEndEditTopic method to whatever method is called when the service returns. In the callback method you could also check if the update was performed without errors and act accordingly.

Andrej Slovenia | Reply

11/6/2009 7:31:26 PM #

Brian1

Will this be updated to Silverlight 3? The data can be handled now with SampleData, etc.

With a quick attempt bringing the 4th article/ZIP file (EditableTreeView), this didn't work in SL3. I didn't do too much research on it, but I wondered ... will that be a complicated task? I'm a bit new at C#. More experience with XAML and a lot with Blend3.

Thanks,

Brian1 United States | Reply

12/21/2009 3:41:26 AM #

Anil

I am getting exception when running with Silverlight 3. Is there anyway to run this in Silverlight 3?

Anil India | Reply

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading





Andrej Tozon

MVP - Client Application Developer

Microsoft Certified Solution Developer

MSN Alerts

View Andrej Tozon's profile on LinkedIn

Subscribe to me on FriendFeed

Andrej Tozon's Facebook profile

Get help from Andrej Tozon!

RecentComments

Comment RSS