解决Silverlight在ChildWindow中进行DragDrop操作问题

     在Codeplex网站上Silverlight Toolkit中,提供了Items controls 控件的拖拽操作支持,可以很方便的对Items Controls(如:ListBox,TreeView)进行拖拽操作。更多有关示例可以查看Silverlight Toolkit Demo

     首先下载 Toolkit 安装包,新建一个Silverlight应用程序,添加对System.Windows.Controls.Toolkit.dll引用,在XAML中添加命名空间xmlns:toolkit ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit" 的引用。因为ListBoxDragDropTarget在该命名空间下。

     添加两个ListBox,并分别添加到ListBoxDragDropTarget中,将AllDrop设置为True。

       <toolkit:ListBoxDragDropTarget Grid.Column="0" Grid.Row="3"
                AllowDrop="true" HorizontalContentAlignment="Stretch"
                VerticalContentAlignment="Stretch" Width="200">
            <ListBox x:Name="fromListBox" DisplayMemberPath="Name"
                    SelectionMode="Multiple">
            </ListBox>
            </toolkit:ListBoxDragDropTarget>
       <toolkit:ListBoxDragDropTarget Grid.Column="0" Grid.Row="3"
                AllowDrop="true" HorizontalContentAlignment="Stretch"
                VerticalContentAlignment="Stretch" Width="200" >
       <ListBox x:Name="toListBox" DisplayMemberPath="Name" SelectionMode="Multiple" >
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Vertical" />
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
            </ListBox>
       </toolkit:ListBoxDragDropTarget>

在后台代码中分别给两个ListBox设置数据源:

ObservableCollection<People> fromList = new ObservableCollection<People> ();
ObservableCollection<People> toList = new ObservableCollection<People>();

fromListBox.ItemsSource = fromList;
toListBox.ItemsSource = toList;

并添加相应数据,People类定义:

public class People
    {
        public string Name { set; get; }
        public int Age { set; get; }
        public People(string name , int age)
        {
            this.Name = name;
            this.Age = age;
        }
    }

运行,即可进行拖拽操作:

image

image

     但是,当我想在ChildWindow中,使用同样的代码进行拖拽操作,却总是不能成功,似乎拖拽操作被禁止。

     最后在官网上,找到了相应问题的解决办法和原因。

     原因

          ChildWindow是一个弹出式窗口,并且在一个单独的visual tree中,所以当前的visual tree并不知道它的存在。

     解决办法

           替代的解决办法是,将ChildWindow添加到当前的visual tree中,并通过设置Visibility 属性,来控制ChildWindow的Open/Close。

MainPage.xaml

ChildWindow1 cw;
        public MainPage()
        {
            InitializeComponent();
            cw = new ChildWindow1();
            LayoutRoot.Children.Add(cw);
            cw.Visibility = System.Windows.Visibility.Collapsed;
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            cw.Visibility = System.Windows.Visibility.Visible; //Show ChildWindow
        }

ChildWindow.xaml

private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
            this.Visibility = System.Windows.Visibility.Collapsed;
        }

     如此就可以在ChildWindow中进行拖拽操作,但是此时的窗口背景没有被禁止操作,为了尽量达到相同的效果。在可以ChildWindow中添加一个Border,并将其背景设置为Gray,透明度设置为0.5,Visiblity设置为Collapsed,在ChildWIndow初始化后将这个Border的Visiblity设置为Visible,退出时设置为Collapsed:

MainPage.xaml

 
<UserControl.. .>
<Grid x:Name="LayoutRoot".. . > // …………
  //   你的代码
  //   . . .. .
 <Border Background="Gray" Visibility="Collapsed" Opacity="0.5"
                x:Name="border_childWindow" />
<Grid>
</UserControl> 
ChildWindow.xaml
private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
            this.Visibility = System.Windows.Visibility.Collapsed;
            MainPage.mainPage.border_childWindow.Visibility = Visibility.Collapsed;
        }
public ChildWindow1()
        {
            InitializeComponent();
            ............
            MainPage.mainPage.border_childWindow.Visibility = Visibility.Visible;
        }
如此,就完整的达到了,在ChildWindow中利用silverlight toolkit对items controls进行拖拽操作!
 
 
 
 
posted @ 2012-08-10 15:09  墨梅  阅读(2022)  评论(7编辑  收藏  举报