问题
iv'e got 2 itemscontrols bound to 2 observable collections
my ItemsControls :
<ItemsControl Grid.Column="4" Name="Pipe19" ItemsSource="{Binding Path=Pipes[19].Checkers}" Style="{StaticResource ItemsControlStyle}" ItemsPanel="{StaticResource TopPipePanelTemplate}" />
<ItemsControl Grid.Column="5" Name="Pipe18" ItemsSource="{Binding Path=Pipes[18].Checkers}" Style="{StaticResource ItemsControlStyle}" ItemsPanel="{StaticResource TopPipePanelTemplate}" />
their definitions through style :
<Style TargetType="{x:Type ItemsControl}" x:Key="ItemsControlStyle">
<Setter Property="ItemTemplate" Value="{StaticResource PipeDataItem}"></Setter>
<Setter Property="AllowDrop" Value="True"></Setter>
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="ItemsControl_MouseLeftButtonDown"></EventSetter>
<EventSetter Event="Drop" Handler="ItemsControl_Drop"></EventSetter>
</Style>
both are considered drop targets , they contain ellipse items which i need to drag from one to the other . the problem is the Add part of the operation doesn't get rendered to the UI .
Visual Helper :
when drag drop as ellipse from the right one to the left :
this is the code which grabs the ellipse and saves the source control
private void ItemsControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
ItemsControl control = (ItemsControl)sender;
UIElement element = control.InputHitTest(e.GetPosition(control)) as UIElement;
if (element != null)
{
Ellipse ellipse = element as Ellipse;
DragSource = control;
DragDrop.DoDragDrop(ellipse, ellipse, DragDropEffects.Copy);
}
}
this is the code where the ellipse is dropped onto it's target :
private void ItemsControl_Drop(object sender, DragEventArgs e)
{
ItemsControl target = (ItemsControl)sender;
Ellipse ellipse = (Ellipse)e.Data.GetData(typeof(Ellipse));
((ObservableCollection<Checker>)DragSource.ItemsSource).Remove(ellipse.DataContext as Checker);
((ObservableCollection<Checker>)target.ItemsSource).Add(ellipse.DataContext as Checker);
}
the Checkers collections are described as follows : (Take notice that they are the itemscontrols ItemsSource :
public class Pipe
{
private ObservableCollection<Checker> checkers;
public ObservableCollection<Checker> Checkers
{
get
{
if (checkers == null)
checkers = new ObservableCollection<Checker>();
return checkers;
}
}
}
after the ItemsControl_Drop event the result is that only the remove updated the UI but the add on the target add not (i would expect that a new item would appear on the left one which i called Add on it's itemsource :
Another Visual Aid :
any ideas ?
回答1:
Maybe the problem is that your adding to the ItemsSource of the ItemsControl instead of directly to the Pipes[#].Checkers. I notice that the remove method is a remove from DragSource.ItemsSource. You probably have a DragTargetControl which ItemsSource you should add to, which will update the Binding. In the way your doing it you might be undoing the Binding if you cast the Binded ItemsSource to an ObservableCollection.
回答2:
I think I know what is going on. I bet Pipes[] is not an ObservableCollection. Try it with Pipe1 and Pipe2. Remove from Pipe1 and add to Pipe2.
回答3:
it turns out the ui element some how loses it's reference if you remove it from one observable collection before adding it to another ,
so i added the ellipse to the target and then removed it from the source .
private void ItemsControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
ItemsControl control = (ItemsControl)sender;
UIElement element = control.InputHitTest(e.GetPosition(control)) as UIElement;
if (element != null && (element is Ellipse))
{
Ellipse ellipse = element as Ellipse;
DragSource = control;
DragDrop.DoDragDrop(ellipse, ellipse, DragDropEffects.Move);
}
}
private void ItemsControl_Drop(object sender, DragEventArgs e)
{
ItemsControl target = (ItemsControl)sender;
Ellipse ellipse = (Ellipse)e.Data.GetData(typeof(Ellipse));
ObservableCollection<Checker> collection = target.ItemsSource as ObservableCollection<Checker>;
Checker checker = ellipse.DataContext as Checker;
collection.Add(checker);
((ObservableCollection<Checker>)DragSource.ItemsSource).Remove(ellipse.DataContext as Checker);
}
来源:https://stackoverflow.com/questions/9647341/update-ui-when-adding-to-observable-collection