开发者

DataTrigger in code

I've tried to get this working, based on the answer I received to [Convert some XAML to C# using WPF][1], but I'm missing something.

I've pasted a sample of my code below.

// uGrid = UniformGrid
uGrid.Columns=2;
// test - setup first ellipse
Ellipse ellipse1 = new Ellipse() { Width=25, Height=25, Fill=Brushes.DodgerBlue, Margin= new Thickness(3), Opacity=0 };
uGrid.C开发者_如何学Gohildren.Add(ellipse1);
var fadeEllipse1 = new DoubleAnimation() { From = 0, To = 1, Duration = TimeSpan.FromSeconds(this.secondsToFade), FillBehavior=FillBehavior.Stop };
Storyboard.SetTarget(fadeEllipse1, ellipse1);
Storyboard.SetTargetProperty(fadeEllipse1, new PropertyPath(Ellipse.OpacityProperty));
Storyboard storyBoard = new Storyboard();

storyBoard.Children.Add(fadeEllipse1);
storyBoard.RepeatBehavior=RepeatBehavior.Forever;

// test - setup 2nd ellipse using example below
Ellipse ellipse2 = new Ellipse() { Width=25, Height=25, Fill=Brushes.DodgerBlue, Margin= new Thickness(3), Opacity=0 };
uGrid.Children.Add(ellipse2);

var style = new Style(typeof(Ellipse));
var trigger = new DataTrigger();
trigger.Binding = new Binding("Opacity") { ElementName = "ellipse1" };
trigger.Value = 1;

Storyboard sb = new Storyboard();

var fadeEllipse2 = new DoubleAnimation() { From = 0, To = 1, Duration = TimeSpan.FromSeconds(this.secondsToFade), FillBehavior=FillBehavior.Stop };
Storyboard.SetTarget(fadeEllipse2, ellipse2);
Storyboard.SetTargetProperty(fadeEllipse2, new PropertyPath(Ellipse.OpacityProperty));
Storyboard.SetTargetName(fadeEllipse2, ellipse2.Name);
sb.Children.Add(fadeEllipse2);
sb.RepeatBehavior=RepeatBehavior.Forever;

trigger.EnterActions.Add(new BeginStoryboard() { Storyboard = sb });
style.Triggers.Add(trigger);

storyBoard.Begin();


There are several mistakes in your code:

  1. You're creating a style, but you don't use it anywhere, you're missing the line

    ellipse2.Style = style;
    
  2. You're trying to bind to an element with the name ellipse1, but it does not exist (having variable with that name is not the same thing). But even if you set the Name of ellipse1, it wouldn't work. You have to declare the name in XAML for that. In code-behind, you can use Source and bind to the other ellipse directly, without using names (which would be a better solution anyway, even if using names worked):

    trigger.Binding = new Binding("Opacity") { Source = ellipse1 };
    
  3. You're comparing whether two doubles have exactly the same value. That's almost always a bad idea, and in this case especially. The Opacity of ellispse1 doesn't change continuously, it changes by jumping. By default, the value changes at most 60 times per second (at least it was that way when I tested it, I didn't find this value documented anywhere). So, the Opacity might start at exactly 0, stay that way for 1/60 s and then jump to 1/60. Because of this, comparing for exact value is even less reliable than when comparing doubles for equality normally (which is not reliable to start with). Using a converter that checks, whether the opacity is greater than 0.99 seems to work for me, but it's still not reliable: if the dispatcher is busy, the opacity can jump, say, from 0.85 straight to 0.12.

    public class GreaterThanConverter : IValueConverter
    {
        public object Convert(
            dynamic value, Type targetType, dynamic parameter, CultureInfo culture)
        {
            return value > parameter;
        }
    
        public object ConvertBack(
            object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
    
    trigger.Binding = new Binding("Opacity")
                        {
                            Source = ellipse1,
                            Converter = new GreaterThanConverter(),
                            ConverterParameter = 0.99
                        };
    trigger.Value = true;
    
  4. Apparently

    A Storyboard tree in a Style cannot specify a TargetName. Remove TargetName.

    So delete the following like, it's not useful anyway.

    Storyboard.SetTargetName(fadeEllipse2, ellipse2.Name);
    
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜