2009-10-09 49 views
0

我有兩個畫筆。我不知道他們是誰的刷子類型。它們可以是ImageBrushes,SolidBrushes或VisualBrushes。我有每個在「刷」類型的變量。如何在WPF中組合畫筆?

我需要結合兩個畫筆。我該怎麼做?

我試過了。但它沒有奏效。這裏是後面和前面畫筆,需要我結合。

Border Bd = new Border(); 
Border Bdr = new Border(); 

Bd.Width = 1.0; 
Bd.Height = 1.0; 

Bd.Background = Back; 
Bdr.Background = Front; 

Bd.Child = Bdr; 

Brush VB = new VisualBrush(Bd); 

我需要這個,因爲我想提出一個自定義動畫類動畫刷。 做了一些測試之後,我得出結論,錯誤在於刷子的組合,而不是在課堂上的其他地方。

生成的畫筆完全透明。


[編輯]

下面是完整BrushAnimation類。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Media.Animation; 
using System.Windows; 
using System.Windows.Media; 
using System.Windows.Controls; 

namespace WPFSoPaTest 
{ 
    class BrushAnimation : AnimationTimeline 
    { 
       protected override Freezable CreateInstanceCore() 
     { 
      return new BrushAnimation(); 
     } 
     public override Type TargetPropertyType 
     { 
      get { return typeof(Brush); } 
     } 
     static BrushAnimation() 
     { 
      FromProperty = DependencyProperty.Register("From", typeof(Brush), 
       typeof(BrushAnimation)); 

      ToProperty = DependencyProperty.Register("To", typeof(Brush), 
       typeof(BrushAnimation)); 
     } 
     public static readonly DependencyProperty FromProperty; 
     public Brush From 
     { 
      get 
      { 
       return (Brush)GetValue(BrushAnimation.FromProperty); 
      } 
      set 
      { 
       SetValue(BrushAnimation.FromProperty, value); 
      } 
     } 
     public static readonly DependencyProperty ToProperty; 
     public Brush To 
     { 
      get 
      { 
       return (Brush)GetValue(BrushAnimation.ToProperty); 
      } 
      set 
      { 
       SetValue(BrushAnimation.ToProperty, value); 
      } 
     } 
     public override object GetCurrentValue(object defaultOriginValue, 
     object defaultDestinationValue, AnimationClock animationClock) 
     { 
      Brush fromVal = ((Brush)GetValue(BrushAnimation.FromProperty)).CloneCurrentValue(); 
      Brush toVal = ((Brush)GetValue(BrushAnimation.ToProperty)).CloneCurrentValue(); 

      if ((double)animationClock.CurrentProgress == 0.0) 
       return fromVal; //Here it workes fine. 

      if ((double)animationClock.CurrentProgress == 1.0) 
       return toVal; //It workes also here fine. 

      toVal.Opacity = (double)animationClock.CurrentProgress; 


      Border Bd = new Border(); 
      Border Bdr = new Border(); 

      Bd.Width = 1.0; 
      Bd.Height = 1.0; 

      Bd.Background = fromVal; 
      Bdr.Background = toVal; 

      Bd.Visibility = Visibility.Visible; 
      Bdr.Visibility = Visibility.Visible; 
      Bd.Child = Bdr; 

      Brush VB = new VisualBrush(Bd); 
      return VB; //But here it return's a transparent brush. 

      //If I return the 'toVal' variable here it animates correctly the opacity. 
     } 
    } 
} 

回答

0

只要你在前刷上有透明像素,上面的方法應該可以工作。如果不是,前刷會覆蓋後刷。你應該提供一個更完整的例子來看看實際發生了什麼。

+0

哎呀我忘了提。爲了做動畫,我經常更換前刷的不透明度。它將在動畫開始時爲0,並且它將以1結束。因此最後它將覆蓋後刷。 它的問題是生成的畫筆完全透明。 – 2009-10-09 08:08:07

+0

也許你不小心設置了VisualBrush「VB」的透明度。用一個不完整的例子很難說出什麼問題。 – bitbonk 2009-10-09 08:52:39

+0

我添加了完整的類。再看一遍。 – 2009-10-09 23:06:31

1

我需要爲畫筆設置動畫的原因是在我用於3D對象的材質中爲畫筆製作動畫。我認爲使畫筆動畫比材質更容易。

我已經使用上面的方法來組合刷子,但它在這裏不起作用。

想了一下之後,我決定讓材質動畫而不是畫筆。 它比動畫畫筆更容易。

[NOTE]
此動畫類適合我的需求。它只會在材質中畫出動畫。我正在使用這個類來替換另一個材質的筆刷。

[NOTE]
'to material'將在最後完全替換'from material',它不會以MaterialGroup結尾。

以下是需要它的MaterialAnimation類。我也有一個Point3DCollectionAnimation類。它可以用來動畫3D網格。這非常有用。 你可以在這個下面找到它。

MaterialAnimation
 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Media.Animation; 
using System.Windows; 
using System.Windows.Media; 
using System.Windows.Controls; 
using System.Windows.Media.Media3D; 

namespace System.Windows.Media.Animation 
{ 
    class MaterialAnimation : AnimationTimeline 
    { 
       protected override Freezable CreateInstanceCore() 
     { 
      return new MaterialAnimation(); 

     } 
     public override Type TargetPropertyType 
     { 
      get { return typeof(Material); } 
     } 
     static MaterialAnimation() 
     { 
      FromProperty = DependencyProperty.Register("From", typeof(Material), 
       typeof(MaterialAnimation)); 

      ToProperty = DependencyProperty.Register("To", typeof(Material), 
       typeof(MaterialAnimation)); 
     } 
     public static readonly DependencyProperty FromProperty; 
     public Material From 
     { 
      get 
      { 
       return (Material)GetValue(MaterialAnimation.FromProperty); 
      } 
      set 
      { 
       SetValue(MaterialAnimation.FromProperty, value); 
      } 
     } 
     public static readonly DependencyProperty ToProperty; 
     public Material To 
     { 
      get 
      { 
       return (Material)GetValue(MaterialAnimation.ToProperty); 
      } 
      set 
      { 
       SetValue(MaterialAnimation.ToProperty, value); 
      } 
     } 
     public override object GetCurrentValue(object defaultOriginValue, 
     object defaultDestinationValue, AnimationClock animationClock) 
     { 
      Material fromVal = ((Material)GetValue(MaterialAnimation.FromProperty)).CloneCurrentValue(); 
      Material toVal = ((Material)GetValue(MaterialAnimation.ToProperty)).CloneCurrentValue(); 

      if ((double)animationClock.CurrentProgress == 0.0) 
       return fromVal; //Here it workes fine. 

      if ((double)animationClock.CurrentProgress == 1.0) 
       return toVal; //It workes also here fine.    

      if (toVal.GetType() == (new DiffuseMaterial()).GetType()) 
       ((DiffuseMaterial)toVal).Brush.Opacity = (double)animationClock.CurrentProgress; 
      else 
       if (toVal.GetType() == (new SpecularMaterial()).GetType()) 
        ((SpecularMaterial)toVal).Brush.Opacity = (double)animationClock.CurrentProgress; 
       else 
        ((EmissiveMaterial)toVal).Brush.Opacity = (double)animationClock.CurrentProgress; 


      MaterialGroup MG = new MaterialGroup(); 

      MG.Children.Add(fromVal); 
      MG.Children.Add(toVal);    

      return MG; 
     } 
    } 
} 


這裏是Point3DCollectionAnimation類。

Point3DCollectionAnimation

 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Media.Animation; 
using System.Windows; 
using System.Windows.Media.Media3D; 

namespace System.Windows.Media.Animation 
{ 
    public class Point3DCollectionAnimation : AnimationTimeline 
    { 
     protected override Freezable CreateInstanceCore() 
     { 
      return new Point3DCollectionAnimation(); 
     } 
     public override Type TargetPropertyType 
     { 
      get { return typeof(Point3DCollection); } 
     } 
     static Point3DCollectionAnimation() 
     { 
      FromProperty = DependencyProperty.Register("From", typeof(Point3DCollection), 
       typeof(Point3DCollectionAnimation)); 

      ToProperty = DependencyProperty.Register("To", typeof(Point3DCollection), 
       typeof(Point3DCollectionAnimation)); 
     } 
     public static readonly DependencyProperty FromProperty; 
     public Point3DCollection From 
     { 
      get 
      { 
       return (Point3DCollection)GetValue(Point3DCollectionAnimation.FromProperty); 
      } 
      set 
      { 
       SetValue(Point3DCollectionAnimation.FromProperty, value); 
      } 
     } 
     public static readonly DependencyProperty ToProperty; 
     public Point3DCollection To 
     { 
      get 
      { 
       return (Point3DCollection)GetValue(Point3DCollectionAnimation.ToProperty); 
      } 
      set 
      { 
       SetValue(Point3DCollectionAnimation.ToProperty, value); 
      } 
     } 
     public override object GetCurrentValue(object defaultOriginValue, 
     object defaultDestinationValue, AnimationClock animationClock) 
     { 
      Point3DCollection fromVal = ((Point3DCollection)GetValue(Point3DCollectionAnimation.FromProperty)); 
      Point3DCollection toVal = ((Point3DCollection)GetValue(Point3DCollectionAnimation.ToProperty)); 

      Point3DCollection ret; 

      int t = 0; 
      if (fromVal.Count > toVal.Count) 
      { 
       ret = fromVal.Clone(); 
       foreach (Point3D tov in toVal) 
       { 
        Point3D frov = fromVal[t]; 
        Point3D newv = new Point3D(); 

        newv.X = (double)animationClock.CurrentProgress * (tov.X - frov.X) + frov.X; 
        newv.Y = (double)animationClock.CurrentProgress * (tov.Y - frov.Y) + frov.Y; 
        newv.Z = (double)animationClock.CurrentProgress * (tov.Z - frov.Z) + frov.Z; 
        ret[t] = newv; 
        t++; 
       } 
      } 
      else 
      { 
       ret = toVal.Clone(); 
       foreach (Point3D frov in fromVal) 
       { 
        Point3D tov = toVal[t]; 
        Point3D newv = new Point3D(); 

        newv.X = (double)animationClock.CurrentProgress * (tov.X - frov.X) + frov.X; 
        newv.Y = (double)animationClock.CurrentProgress * (tov.Y - frov.Y) + frov.Y; 
        newv.Z = (double)animationClock.CurrentProgress * (tov.Z - frov.Z) + frov.Z; 
        ret[t] = newv; 
        t++; 
       } 
      } 

      return ret; 
     } 
    } 
} 

我希望這些類是有用誰需要他們。我在網上搜索他們,但沒有找到他們。我相信有更多的人需要這些課程。

請發表評論。

1

我發現了這個問題。可視化筆刷不可冷凍。要工作的代碼,我需要找到一種方法來凍結畫筆。

1

亞倫,我用你的BrushAnimation類如上所示,它適用於我的特定需求。但是,我注意到StackOverflow在Creative Commons許可下運行。因此,我在技術上不能在未經您許可的情況下在我的商業應用程序中使用該類(我不想在Creative Commons許可下使用該類)。你願意給我許可嗎?我仍然可以信任你的工作。

我找不到任何其他方式與您聯繫,因爲我無法發表評論。

+1

是的,你可以使用該課程,如果你想。如果你給了我一些信用,但不一定是這樣,那會很好。 – 2011-03-13 23:21:42

+0

太棒了!謝謝。我會在該計劃的適當位置給予獎勵。 – skybluecodeflier 2011-03-14 17:15:06

0

可以使用visualbrush實現這一

<Grid.Background> 
     <VisualBrush> 
       <VisualBrush.Visual> 
        <Grid 
         Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type FrameworkElement}}, Mode=OneWay}" 
         Height="{Binding Path=ActualHeight, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type FrameworkElement}}, Mode=OneWay}"> 

         <Rectangle Fill="Blue" /> 
         <Image Source="your image path" Stretch="Uniform" /> 

        </Grid> 
       </VisualBrush.Visual> 
      </VisualBrush> 
     </Grid.Background>