Wpf 添加到可观察集合时更新UI

Wpf 添加到可观察集合时更新UI,wpf,drag-and-drop,observablecollection,Wpf,Drag And Drop,Observablecollection,iv'e有2个ItemsControl绑定到2个可观察集合 我的项目控件: <ItemsControl Grid.Column="4" Name="Pipe19" ItemsSource="{Binding Path=Pipes[19].Checkers}" Style="{StaticResource ItemsControlStyle}" ItemsPanel="{StaticReso

iv'e有2个ItemsControl绑定到2个可观察集合

我的项目控件:

    <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}" />
   <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> 
    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); 
    } 
这是将椭圆放置到其目标上的代码:

    <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}" />
   <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> 
    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); 
    } 
private void ItemsControl\u Drop(对象发送方,DragEventArgs e)
{
ItemsControl目标=(ItemsControl)发送方;
椭圆=(椭圆)e.Data.GetData(类型(椭圆));
((ObservableCollection)DragSource.ItemsSource).删除(椭圆.DataContext作为检查器);
((ObservaleCollection)target.ItemsSource).Add(作为检查器的ellipse.DataContext);
} 
checker集合描述如下:(注意它们是itemscontrols ItemsSource:

public class Pipe  
{    
    private ObservableCollection<Checker> checkers;
    public ObservableCollection<Checker> Checkers
    {
        get 
        {
            if (checkers == null)
                checkers = new ObservableCollection<Checker>();
            return checkers; 
        }            
    }        
}
  
公共类管道
{    
私人可观察收集检查器;
公共可观测收集检查器
{
得到
{
if(checkers==null)
checkers=新的ObservableCollection();
返回跳棋;
}            
}        
}
ItemsControl_Drop事件发生后,结果是只有remove更新了UI,但目标add上的add没有更新(我希望左侧会出现一个新项目,我称之为其itemsource上的add:

另一种视觉辅助工具:

    <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}" />
   <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> 
    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); 
    } 


有什么想法吗?

可能问题在于您将添加到ItemsControl的ItemsSource,而不是直接添加到管道[#]checker。 我注意到remove方法是从DragSource.ItemsSource中删除的。 您可能有一个DragTargetControl来控制应该添加到哪个ItemsSource,它将更新绑定。
如果您将绑定的项目资源强制转换为可观察的集合,那么在您这样做的过程中,您可能正在撤消绑定。

我想我知道发生了什么。我打赌管道[]不是可观察集合。请使用Pipe1和Pipe2进行尝试。从Pipe1中删除并添加到Pipe2。

如果删除ui元素,它会丢失其引用 从一个可观察的集合添加到另一个集合之前

因此,我将椭圆添加到目标,然后将其从源中删除

    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);

    }         
private void items控件\u MouseLeftButtonDown(对象发送器,MouseButtonEventArgs e)
{
ItemsControl控件=(ItemsControl)发送方;
UIElement元素=作为UIElement的control.inputItTest(e.GetPosition(control));
if(元素!=null&&(元素为椭圆))
{
椭圆=元素为椭圆;
DragSource=控制;
DragDrop.DoDragDrop(椭圆、椭圆、DragDropEffects.Move);
}
}
私有无效项控件放置(对象发送方,DragEventArgs e)
{
ItemsControl目标=(ItemsControl)发送方;
椭圆=(椭圆)e.Data.GetData(类型(椭圆));
ObservableCollection集合=target.ItemsSource作为ObservableCollection;
Checker Checker=eliple.DataContext作为Checker;
收集。添加(检查);
((ObservableCollection)DragSource.ItemsSource).删除(椭圆.DataContext作为检查器);
}         

可能发生的情况是,添加尚未具有集合。请尝试重新分解为:公共类管道{private observedcollection checkers=new observedcollection();公共observedcollection checkers{get{return checkers;}在添加之前和之后进行调试以获得计数。然后在删除之前尝试添加。在设置绑定之前,iv'e尝试创建它们,但仍然不起作用。@Blam iv'e注意到,当我调用add时,它不会进入checkers集合,我在其中放置断点,这有点奇怪,好像它现在无法识别集合i在它上绑定到..有什么想法吗?好的,我不知道我可以撤消绑定,你是说((ObservaleCollection)target.ItemsSource)。Add(ellipse.DataContext作为检查器);将其视为一个新的ItemsSource?您没有真正接触到绑定。但是您也没有真正更新绑定指向的源。绑定引用原始对象。您可能希望通过原始模型更新集合。我不建议通过管道访问属性[19]而是将控件的DataContext设置为{Binding Path=Pipes[19]},将ItemsSource设置为{Binding Path=Checkers}我会试试看,虽然我真的不明白为什么这不是我的绑定。事实并非如此,在移除椭圆之前我应该添加它,它将椭圆称为断开连接的项目。他们不必感到抱歉,因为我已经解决了这个问题。我应该发布我的答案。唯一的问题是,显然移除了el在将椭圆添加到另一个项目之前,从itemscontrol中选择lipse,使其被调试器称为断开连接的项目。我猜它在wpf框架中不知何故丢失了引用。请阅读我第一条注释的最后一句。“并在删除之前尝试添加。”