在SL3中拖放问题

时间:2010-01-29 18:54:12

标签: c# silverlight

我在Silverlight 3中有一个UserControl。

LayoutRoot网格包含一个子网,一个网格,由三列和两行组成。

以下是布局:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>

        <Grid x:Name="NavigationGrid" Grid.RowSpan="2" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
            <!-- Content placed here -->
        </Grid>
        <Border Background="Transparent"  Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="0" BorderBrush="Black" BorderThickness="0,0,0,0" Height="38" HorizontalAlignment="Stretch" Width="Auto">
            <!-- Content placed here -->
        </Border>
        <Border Background="Transparent" Grid.Column="2" Grid.Row="1" Grid.RowSpan="2" BorderBrush="Black" BorderThickness="0,0,1,1" Height="Auto" VerticalAlignment="Stretch" Width="38">
            <!-- Content placed here -->
        </Border>
        <Border Grid.Row="1" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="Auto" Background="White" BorderBrush="Black" BorderThickness="0,0,1,1" Width="Auto">
            <!-- Content placed here -->
        </Border>
    </Grid>
</Grid>

我有使用装饰器的功能。装饰者将自己附加到指定的框架元素。

当用户单击位于名为NavigationGrid的网格的右上角的按钮时,将调用此功能。该按钮包含图钉图标。此功能从其父级子级中删除NavigationGrid网格,并将其添加到LayoutRoot网格的子级。装饰者允许用户能够在屏幕上拖动网格。

如果用户再次单击图钉按钮,则预期的功能是从LayoutRoot子项中删除网格,并使用Grid.Column,Grid.RowSpan等将其添加回原始父项的子项。值。

我遇到的问题是当NavigationGrid网格最初从它的父节点中删除时,网格中的所有其他元素都会调整大小等等。这是可以的,因为它是我想要的。但是,当网格被放回到它的父母的孩子身上时,它的位置与原来的不同。我检查了Margin属性,并将其设置为0.因此,因为它的位置与它的原始位置不同,所以我以编程方式将其边距设置为负值,将其视觉上放回原来的位置。这会抛弃其他元素的位置,一切都开始重叠等。

所以,我的问题是,是否有人知道如何实现此功能,以便可以从其父级移除NavigationGrid网格,然后将其放回到其父级,其原始位置/位置是否正常?

感谢。

克里斯

以下是UI的屏幕截图。出于显而易见的原因,我已经将UI的某些部分涂黑了。标签为“Processes”的左侧网格是用户应该能够“取消固定”并四处移动的网格,这确实有效,它是将其放回原位产生问题的功能。

alt text http://i45.tinypic.com/4rcpp5.jpg

请参阅下面的代码,该方法可以处理pin / unpin功能:

public void PinMenu(object parameter)
    {
        if (_navigationGridPinned)
        {
            PushPinImagePath = new Uri("../Images/pushpin_pinned.png", UriKind.Relative);

            _navigationGridPinned = false;

            var e = parameter as MouseButtonEventArgs;

            if (!e.IsNull())
            {
                var grid = ValidationHelper.GetPanelFromVisualTree(Application.Current.RootVisual, "NavigationGrid") as Grid;

                if (!grid.IsNull())
                {
                    grid.MeasureAndArrange();

                    double gridHeight = grid.ActualHeight;

                    double gridWidth = grid.ActualWidth;

                    grid.HorizontalAlignment = HorizontalAlignment.Left;

                    grid.VerticalAlignment = VerticalAlignment.Top;

                    grid.Margin = new Thickness(0, 0, 0, 0);

                    var parent = grid.Parent as Grid;

                    parent.Children.Remove(grid);

                    var layoutRootGrid = parent.Parent as Grid;

                    if (!layoutRootGrid.IsNull())
                    {
                        _originalOffset = parent.TransformToVisual(layoutRootGrid).Transform(new Point(0, 0));

                        grid.Height = gridHeight;

                        grid.Width = gridWidth;

                        var border = grid.Children[0] as Border;

                        if (!border.IsNull())
                        {
                            border.BorderThickness = new Thickness(1, 1, 1, 1);

                            var backgroundBrush = App.Current.Resources["GradientBlueBrush"] as LinearGradientBrush;

                            if (!backgroundBrush.IsNull())
                            {
                                border.Background = backgroundBrush;
                            }
                        }

                        layoutRootGrid.Children.Add(grid);

                        Grid.SetRow(grid, 1);

                        _adorner = new Adorner();

                        _adorner.HorizontalAlignment = HorizontalAlignment.Left;

                        _adorner.VerticalAlignment = VerticalAlignment.Top;

                        _adorner.AdornedElement = grid as FrameworkElement;

                        _adorner.adorned_MouseLeftButtonDown((FrameworkElement)grid, e);
                    }
                }
            }
        }
        else
        {
            _navigationGridPinned = true;

            PushPinImagePath = new Uri("../Images/pushpin.png", UriKind.Relative);

            var grid = ValidationHelper.GetPanelFromVisualTree(Application.Current.RootVisual, "NavigationGrid") as Grid;

            if (!grid.IsNull())
            {
                var parent = grid.Parent as Grid;

                if (parent != null)
                {
                    var mainViewGrid = ValidationHelper.GetPanelFromVisualTree(Application.Current.RootVisual, "MainViewGrid") as Grid;

                    var parentGrid = mainViewGrid.Parent as Grid;

                    var layoutRootGrid = parentGrid.Parent as Grid;

                    var currentOffset = grid.TransformToVisual(layoutRootGrid).Transform(new Point(0, 0));

                    Point p = new Point(-(currentOffset.X - _originalOffset.X), -(currentOffset.Y - _originalOffset.Y));

                    parent.Children.Remove(grid);

                    parent.UpdateLayout();

                    grid.MeasureAndArrange();

                    var navBorder = ValidationHelper.GetPanelFromVisualTree(Application.Current.RootVisual, "NavBorder") as Border;

                    var tabMenuBorder = ValidationHelper.GetPanelFromVisualTree(Application.Current.RootVisual, "TabMenuBorder") as Border;

                    var processMapBorder = ValidationHelper.GetPanelFromVisualTree(Application.Current.RootVisual, "ProcessMapBorder") as Border;

                    mainViewGrid.Children.Clear();

                    var border = grid.Children[0] as Border;

                    if (!border.IsNull())
                    {
                        border.Background = new SolidColorBrush(Colors.Transparent);

                        border.BorderThickness = new Thickness(1, 0, 1, 1);
                    }

                    _adorner.HorizontalAlignment = HorizontalAlignment.Left;

                    _adorner.VerticalAlignment = VerticalAlignment.Top;

                    _adorner.Margin = new Thickness(0, 0, 0, 0);

                    _adorner.AdornedElement = null;

                    mainViewGrid.Children.Add(tabMenuBorder);

                    Grid.SetColumn(tabMenuBorder, 2);

                    Grid.SetRowSpan(tabMenuBorder, 2);

                    Grid.SetRow(tabMenuBorder, 1);

                    mainViewGrid.Children.Add(processMapBorder);

                    Grid.SetColumn(processMapBorder, 1);

                    Grid.SetRow(processMapBorder, 1);

                    mainViewGrid.Children.Add(navBorder);

                    Grid.SetColumnSpan(navBorder, 2);

                    Grid.SetRow(navBorder, 0);

                    Grid.SetColumn(navBorder, 1);

                    grid.Margin = new Thickness(p.X, p.Y, 0, 0);

                    mainViewGrid.Children.Add(grid);

                    Grid.SetColumn(grid, 0);

                    Grid.SetRow(grid, 0);

                    Grid.SetRowSpan(grid, 2);
                }
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

一种策略可能是将“NavigationGrid”包装在容器网格“ContainerGrid”中,固定时为“Visible”,取消固定时为“Collapsed”。这样,在引脚操作期间重新生成父项时,可以将“NavigationGrid”放回到命名的“ContainerGrid”中。