Safwan
Safwan

Reputation: 171

how to delete a selected template in a listbox

i have a listbox which has a data template binded to task from xml file,i want to delete selected template on button click,but its throws me an exception "Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead."

here is the code for xaml

 <TabItem>
        <Canvas Height="700" Width="850">
            <Canvas.Resources>
                <XmlDataProvider x:Key="Tasks" XPath="tasks"
       Source="http://store.tymesheet.com/templates/Graphic-Designer.xml"/>
                <DataTemplate x:Key="tasktemplate1">
                    <Canvas Height="50" Width="850" >
                        <Label Content="{Binding XPath=name}" Height="30"
                   Width="170" Canvas.Top="10" Canvas.Left="150" 
                   Background="LightGray"/>
                        <TextBox Height="30" Width="120" Canvas.Top="10"
                     Canvas.Left="370" Background="AliceBlue"/>
                        <Label  Canvas.Left="500" Canvas.Top="10">$</Label>
                        <Button Tag="{Binding}" Click="deletebuttonclick" 
                    Canvas.Top="12" Height="10" Width="30"
                    Canvas.Left="600"/>
                    </Canvas>
                </DataTemplate>
            </Canvas.Resources>
            <ListBox ItemTemplate="{StaticResource tasktemplate1}"
      ItemsSource="{Binding Path=ChildNodes, Source={StaticResource Tasks}}" 
      x:Name="tasklistbox" Height="700" Width="850"/>
            <Label Canvas.Top="-18" Canvas.Left="185">Select Task</Label>
            <Label Canvas.Top="-18" Canvas.Left="377" RenderTransformOrigin="0.58,0.462">Enter Bill Rates</Label>
            <Button Canvas.Left="39" Canvas.Top="575" Width="139">Click to add the task</Button>
        </Canvas>
    </TabItem>

here is the code behind for delete button

 private void deletebuttonclick(object sender,RoutedEventArgs e)
    {
        tasklistbox.Items.Remove(tasklistbox.SelectedItem);    
    }

where am i wrong?,help.thanx.

Upvotes: 0

Views: 491

Answers (2)

Rohit Vats
Rohit Vats

Reputation: 81253

If you want to remove the item, then I would suggest to create ObservableCollection of XmlNode and bind ItemsSource with that. I suggested to use ObservableCollection because it implements INotifyCollectionChanged so whenever list is updated target which in your case is ListBox will automatically be updated.


In code behind (Add System.Collections.ObjectModel namespace to use ObservableCollection<T>)

public MainWindow()
{
    InitializeComponent();

    XmlDocument doc = new XmlDocument();
    doc.Load("http://store.tymesheet.com/templates/Software-Developer.xml");
    var taskList = doc.ChildNodes.OfType<XmlNode>()
                    .Where(node => node.Name == "tasks")
                    .SelectMany(node => node.ChildNodes.OfType<XmlNode>());
    Tasks = new ObservableCollection<XmlNode>(taskList);

    this.DataContext = this;
}

public ObservableCollection<XmlNode> Tasks { get; set; }

private void deletebuttonclick(object sender, RoutedEventArgs e)
{
   XmlNode selectedNode = ((Button)sender).DataContext as XmlNode;
   Tasks.Remove(selectedNode);
}

Of course you need to update XAML as well:

<ListBox ItemsSource="{Binding Tasks}"
         ItemTemplate="{StaticResource tasktemplate1}"
         x:Name="listBox" Height="700" Width="850"/>

Upvotes: 1

Sheridan
Sheridan

Reputation: 69989

The error that you displayed is fairly self explanatory:

Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead.

Clearly, as you should know, you used the ItemsSource property on the ListBox:

<ListBox ItemTemplate="{StaticResource tasktemplate1}"
    ItemsSource="{Binding Path=ChildNodes, Source={StaticResource Tasks}}" 
    x:Name="tasklistbox" Height="700" Width="850" />

The error is telling you to Access and modify elements with ItemsControl.ItemsSource instead. So instead of not doing what it says:

private void deletebuttonclick(object sender,RoutedEventArgs e)
{
    tasklistbox.Items.Remove(tasklistbox.SelectedItem);    
}

Try actually doing what it says:

private void deletebuttonclick(object sender,RoutedEventArgs e)
{
    tasklistbox.ItemsSource = null; 
}

Or even better:

private void deletebuttonclick(object sender,RoutedEventArgs e)
{
    ChildNodes = null; 
}

UPDATE >>>

So it seems that we have another new user that asks one thing and when given that thing asks for another thing without so much as a 'thank you'... shame... a real shame.

First you need to data bind to the ListBox.SelectedItem property so that you know which item is selected:

<ListBox ItemTemplate="{StaticResource tasktemplate1}" SelectedItem="{Binding Item}"
    ItemsSource="{Binding Path=ChildNodes, Source={StaticResource Tasks}}" 
    x:Name="tasklistbox" Height="700" Width="850" />

This Item property should be of the same type as the items in the ChildNodes collection... if it's not clear enough - you need to add that property next to your collection property. Then to remove that item in your handler, you just need to do this:

private void deletebuttonclick(object sender,RoutedEventArgs e)
{
    ChildNodes.Remove(Item);
}

Upvotes: 2

Related Questions