Reputation: 171
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
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
Reputation: 69989
The error that you displayed is fairly self explanatory:
Operation is not valid while
ItemsSource
is in use. Access and modify elements withItemsControl.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