none
Button.RenderTransform.SetValue(ScaleTransform.ScaleYProperty, -1.0); 抛出异常 RRS feed

  • 问题

  • 在以下代码中抛出异常

    protected virtual void OnCollapseModeChanged(GridSplitterCollapseMode collapseMode)
    {
    ...
     if (collapseMode == GridSplitterCollapseMode.Previous)
                    {
                        if (_elementHorizontalGridSplitterButton != null)
                        {
                            _elementHorizontalGridSplitterButton.RenderTransform.SetValue(ScaleTransform.ScaleYProperty, -1.0);
                        }
                        if (_elementVerticalGridSplitterButton != null)
                        {
                            _elementVerticalGridSplitterButton.RenderTransform.SetValue(ScaleTransform.ScaleXProperty, -1.0);
                        }
                    }
                    else if (collapseMode == GridSplitterCollapseMode.Next)
                    {
                        if (_elementHorizontalGridSplitterButton != null)
                        {
                            _elementHorizontalGridSplitterButton.RenderTransform.SetValue(ScaleTransform.ScaleYProperty, 1.0);
                        }
                        if (_elementVerticalGridSplitterButton != null)
                        {
                            _elementVerticalGridSplitterButton.RenderTransform.SetValue(ScaleTransform.ScaleXProperty, 1.0);
                        }
                    }
    }


    非法操作异常:无法设置对象“System.Windows.Media.ScaleTransform”上的属性,因为它处于只读状态。。。

    以上代码在silverlight中运行良好,在wpf应用中就异常。

    完整代码可以在此下载gridsplitter

    WpfApplication1为wpf版本,报异常。

    CollapsingGridSplitter为silverlight版本,运行正常。

    2012年4月25日 16:19

答案

  • SL和WPF是两套技术,两套不同的代码,所以你在SL中的代码和方法到WPF不一定能成功。

    我看了SL的效果,介绍你一个我曾经自己写的WPF一样的效果吧,比较简单,没有从 GridSplitter 来继承,而是直接用了Grid的行列来做的: https://skydrive.live.com/?cid=51B2FDD068799D15&id=51B2FDD068799D15%21904

    原帖:http://social.msdn.microsoft.com/Forums/en-us/wpf/thread/1e7b0db3-f374-4a15-9514-0e2034367304

    至于你给的代码的问题,解决起来很简单,在OnCollapseModeChanged 方法中加上 IsLoaded判断,在没有Loaded之前,RenderTransform为只读:

            protected virtual void OnCollapseModeChanged(GridSplitterCollapseMode collapseMode)
            {
              if (this.IsLoaded)
              {
                // Hide the handles if the CollapseMode is set to None.
                if (collapseMode == GridSplitterCollapseMode.None)
                {
         ......


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年4月26日 9:07
    版主
  • 我明白你的意思了,但是WPF和SL不一样,RenderTransform在没有Loaded前,无法对其设置值。

    不过你可以看到,设置RenderTransform的目的只是为了让按钮转个方向,所以为了达到这个目的,我们可以不通过RenderTransform, 而采用其他方案,比如用不同方向的切图资源放置在 ToggleButton ,然后将其替换。 

    或者,我们还是可以用原来的代码,不过让其在Button.Loaded事件中执行:

            protected virtual void OnCollapseModeChanged(GridSplitterCollapseMode collapseMode)
            {
              if (_elementHorizontalGridSplitterButton != null)
              {
                _elementHorizontalGridSplitterButton.Loaded += new RoutedEventHandler(_elementHorizontalGridSplitterButton_Loaded);
              }
              if (_elementVerticalGridSplitterButton != null)
              {
                _elementVerticalGridSplitterButton.Loaded += new RoutedEventHandler(_elementVerticalGridSplitterButton_Loaded);
              }
            }
    
            void _elementHorizontalGridSplitterButton_Loaded(object sender, RoutedEventArgs e)
            {
              _elementHorizontalGridSplitterButton.Loaded -= _elementHorizontalGridSplitterButton_Loaded;
              if (this.CollapseMode == GridSplitterCollapseMode.None)
              {
                _elementHorizontalGridSplitterButton.Visibility = Visibility.Collapsed;
              }
              else
              {
                _elementHorizontalGridSplitterButton.Visibility = Visibility.Visible;
    
                if (this.CollapseMode == GridSplitterCollapseMode.Previous)
                {
                  _elementHorizontalGridSplitterButton.RenderTransform.SetValue(ScaleTransform.ScaleYProperty, -1.0);
                }
                else if (this.CollapseMode == GridSplitterCollapseMode.Next)
                {
                  _elementHorizontalGridSplitterButton.RenderTransform.SetValue(ScaleTransform.ScaleYProperty, 1.0);
                }
              }
            }
    
            void _elementVerticalGridSplitterButton_Loaded(object sender, RoutedEventArgs e)
            {
              _elementVerticalGridSplitterButton.Loaded -= _elementVerticalGridSplitterButton_Loaded;
              if (this.CollapseMode == GridSplitterCollapseMode.None)
              {
                _elementVerticalGridSplitterButton.Visibility = Visibility.Collapsed;
              }
              else
              {
                _elementVerticalGridSplitterButton.Visibility = Visibility.Visible;
    
                if (this.CollapseMode == GridSplitterCollapseMode.Previous)
                {
                  _elementVerticalGridSplitterButton.RenderTransform.SetValue(ScaleTransform.ScaleXProperty, -1.0);
                }
                else if (this.CollapseMode == GridSplitterCollapseMode.Next)
                {
                  _elementVerticalGridSplitterButton.RenderTransform.SetValue(ScaleTransform.ScaleXProperty, 1.0);
                }
              }
            }
    


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年4月30日 9:49
    版主

全部回复

  • SL和WPF是两套技术,两套不同的代码,所以你在SL中的代码和方法到WPF不一定能成功。

    我看了SL的效果,介绍你一个我曾经自己写的WPF一样的效果吧,比较简单,没有从 GridSplitter 来继承,而是直接用了Grid的行列来做的: https://skydrive.live.com/?cid=51B2FDD068799D15&id=51B2FDD068799D15%21904

    原帖:http://social.msdn.microsoft.com/Forums/en-us/wpf/thread/1e7b0db3-f374-4a15-9514-0e2034367304

    至于你给的代码的问题,解决起来很简单,在OnCollapseModeChanged 方法中加上 IsLoaded判断,在没有Loaded之前,RenderTransform为只读:

            protected virtual void OnCollapseModeChanged(GridSplitterCollapseMode collapseMode)
            {
              if (this.IsLoaded)
              {
                // Hide the handles if the CollapseMode is set to None.
                if (collapseMode == GridSplitterCollapseMode.None)
                {
         ......


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年4月26日 9:07
    版主
  • Bob, 谢谢你的解答。 我按你所讲修改了代码,只是消除了异常,功能上还是不正确(跟我之前注释掉该片代码的运行结果差不多);与SL的正常运行结果相差太大。

    因为CollapseMode 在程序启动后不会被人为修改,只在最初的mainwindow.xaml初始化。

    <controls:ExtendedGridSplitter Grid.Column="1"
                                               VerticalAlignment="Stretch"
                                               HorizontalAlignment="Center"
                                               Width="10"
                                               CollapseMode="Next"
                                               Background="LightBlue" />

    如其中的  CollapseMode="Next"  。

    2012年4月26日 11:57
  • 至于你给的代码的问题,解决起来很简单,在OnCollapseModeChanged 方法中加上 IsLoaded判断,在没有Loaded之前,RenderTransform为只读:

            protected virtual void OnCollapseModeChanged(GridSplitterCollapseMode collapseMode)
            {
              if (this.IsLoaded)
              {
                // Hide the handles if the CollapseMode is set to None.
                if (collapseMode == GridSplitterCollapseMode.None)
                {
         ......


    如此修改,CollapseMode changed的时候this.IsLoaded 必然是否, 方法内代码将永不执行。
    2012年4月27日 8:13
  • 我明白你的意思了,但是WPF和SL不一样,RenderTransform在没有Loaded前,无法对其设置值。

    不过你可以看到,设置RenderTransform的目的只是为了让按钮转个方向,所以为了达到这个目的,我们可以不通过RenderTransform, 而采用其他方案,比如用不同方向的切图资源放置在 ToggleButton ,然后将其替换。 

    或者,我们还是可以用原来的代码,不过让其在Button.Loaded事件中执行:

            protected virtual void OnCollapseModeChanged(GridSplitterCollapseMode collapseMode)
            {
              if (_elementHorizontalGridSplitterButton != null)
              {
                _elementHorizontalGridSplitterButton.Loaded += new RoutedEventHandler(_elementHorizontalGridSplitterButton_Loaded);
              }
              if (_elementVerticalGridSplitterButton != null)
              {
                _elementVerticalGridSplitterButton.Loaded += new RoutedEventHandler(_elementVerticalGridSplitterButton_Loaded);
              }
            }
    
            void _elementHorizontalGridSplitterButton_Loaded(object sender, RoutedEventArgs e)
            {
              _elementHorizontalGridSplitterButton.Loaded -= _elementHorizontalGridSplitterButton_Loaded;
              if (this.CollapseMode == GridSplitterCollapseMode.None)
              {
                _elementHorizontalGridSplitterButton.Visibility = Visibility.Collapsed;
              }
              else
              {
                _elementHorizontalGridSplitterButton.Visibility = Visibility.Visible;
    
                if (this.CollapseMode == GridSplitterCollapseMode.Previous)
                {
                  _elementHorizontalGridSplitterButton.RenderTransform.SetValue(ScaleTransform.ScaleYProperty, -1.0);
                }
                else if (this.CollapseMode == GridSplitterCollapseMode.Next)
                {
                  _elementHorizontalGridSplitterButton.RenderTransform.SetValue(ScaleTransform.ScaleYProperty, 1.0);
                }
              }
            }
    
            void _elementVerticalGridSplitterButton_Loaded(object sender, RoutedEventArgs e)
            {
              _elementVerticalGridSplitterButton.Loaded -= _elementVerticalGridSplitterButton_Loaded;
              if (this.CollapseMode == GridSplitterCollapseMode.None)
              {
                _elementVerticalGridSplitterButton.Visibility = Visibility.Collapsed;
              }
              else
              {
                _elementVerticalGridSplitterButton.Visibility = Visibility.Visible;
    
                if (this.CollapseMode == GridSplitterCollapseMode.Previous)
                {
                  _elementVerticalGridSplitterButton.RenderTransform.SetValue(ScaleTransform.ScaleXProperty, -1.0);
                }
                else if (this.CollapseMode == GridSplitterCollapseMode.Next)
                {
                  _elementVerticalGridSplitterButton.RenderTransform.SetValue(ScaleTransform.ScaleXProperty, 1.0);
                }
              }
            }
    


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年4月30日 9:49
    版主