views:

39

answers:

0

I have a ListView that uses a GridView and it is bound to an observable collection. On load I populate the collection and it shows up in the UI as expected. The problem happens when I try to manipulate the ObservableCollection later on; if I call RemoveAt( n ) or Clear() on the collection I get an invalid cast exeception that can't convert MS.Internal.NamedObject to the type of object stored in the collection.

From what I have read the DataGrid uses NamedObject to support adding rows, I can't find any reference to NamedObject with list views though. Why is this exception happening and how I can fix the underlying problem without resorting to try/catch blocks around each Clear or RemoveAt?

Exception:

{"Unable to cast object of type 'MS.Internal.NamedObject' to type 'User'."}

ListView Initialization

<ListView Name="listViewUsers" Grid.Row="0" ItemsSource="{Binding Path=Users}" GridViewColumnHeader.Click="GridViewHeader_Click">
    <ListView.Resources>
        <DataTemplate x:Key="UserControl">
            <StackPanel Orientation="Horizontal">
                <Button
                    cmd:Click.Command="{Binding Path=Model.UserService.DeleteUserCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
                    cmd:Click.CommandParameter="{Binding Path=Content, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}"
                    >Delete</Button>
                <Button
                    cmd:Click.Command="{Binding Path=Model.EditUserCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
                    cmd:Click.CommandParameter="{Binding Path=Content, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}">                              Edit</Button>
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Key="IsEnabledTemplate"> 
            <CheckBox IsChecked="{Binding IsEnabled}" IsEnabled="False" />
        </DataTemplate>

        <Style TargetType="{x:Type ListViewItem}">
            <EventSetter Event="MouseDoubleClick" Handler="ListViewUser_DoubleClick" />
        </Style>
    </ListView.Resources>
    <ListView.View>
        <GridView>
            <GridViewColumn CellTemplate="{StaticResource UserControl}" />
            <GridViewColumn Header="Is Enabled" Width="auto" CellTemplate="{StaticResource IsEnabledTemplate}" />
            <GridViewColumn Header="User Id" DisplayMemberBinding="{Binding Id}" />
            <GridViewColumn Header="First Name" Width="auto" DisplayMemberBinding="{Binding FirstName}"/>
            <GridViewColumn Header="Last Name" Width="auto" DisplayMemberBinding="{Binding LastName}"/>
            <GridViewColumn Header="User Name" Width="auto" DisplayMemberBinding="{Binding UserName}" />
        </GridView>
    </ListView.View>
</ListView>

Code (heavily snipped):

public class UserService : IUserService
{
    private readonly ILoggerFacade _logger;
    private readonly IEventAggregator _eventAggregator;
    private ObservableCollection<EnterpriseUser> _users;


    public UserService( ILoggerFacade logger, IEventAggregator eventAggregator )
    {
        _users = new ObservableCollection<User>();
    }

    public ObservableCollection<EnterpriseUser> Users
    {
        get { return _users; }
    }


    public void DeleteUserCommand_Execute( User)
    {
        try
        {

            bool success = DeleteUser( user );

            if( !success )
            {
                _logger.Log( string.Format( "Enable to delete user: {0}", user.ToString() ),
                             Category.Debug, Priority.None );
            } else
            {
                _logger.Log( string.Format( "User deleted: {0}", user.ToString() ), Category.Debug,
                             Priority.None );
            }

            Users.Remove( user );

        } catch( Exception e )
        {
            _logger.Log( String.Format( "Exception occurred while trying to delete user: {0}", e.Message ), Category.Exception, Priority.None );
        }
    }
}