无效的属性值属性数据未知

时间:2016-06-21 10:17:56

标签: c# windows xaml

我尝试在我的应用中创建自定义进度圈,所以我做了一个效果很好的示例。但是,当我将该代码放入我的应用程序时,我有错误消息 - > Invalid attribute value Unknown for property Data.

以下代码两侧都是相同的。我不明白附加什么......

有人可以帮助我吗?

PS:我看到的唯一区别是我通过调度员触发动画

internal async void ReflowController_OnMessageReceived(string message)
{
  await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
  () =>
  {
    NotificationBar_Message.Text = message;

    Point initialPoint = new Point(13, 1);
    AnimationHelper.AnimatePath(this.progressPath, 12, initialPoint, 360, 0.0111, 1);

    [...]

    }
}

这是我的示例代码

MainPage.xaml中

<Page x:Class="ArcAnimationSample.MainPage"
    IsTabStop="false"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ArcAnimationSample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">

        <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
            <RowDefinition Height="100"/>
        </Grid.RowDefinitions>

        <!-- circle progress -->
        <Grid Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">
            <!-- secondary path -->
            <Path Stroke="#40FFFFFF" StrokeThickness="2"  HorizontalAlignment="Center" VerticalAlignment="Center" Height="26" Width="26" Data="m 13,1 A 12,12 0 0 1 13,25 A 12,12 0 0 1 13,1"/>
            <!-- path to animate -->
            <Path x:Name="progressPath" Stroke="White" StrokeThickness="2" HorizontalAlignment="Center" VerticalAlignment="Center" Height="26" Width="26" Data="m 13,1 A 12,12 0 0 1 13,1 A 12,12 0 0 1 13,1"/>
            <!-- icon inside -->
            <Viewbox Width="12" Height="9" >
                <Canvas Width="12" Height="9">
                    <Canvas>
                        <Path Fill="White" Data="F1 M 10.920,0.000 L 12.000,1.078 L 4.055,9.000 L 0.000,4.955 L 1.080,3.878 L 4.055,6.845 L 10.920,0.000 Z"/>
                    </Canvas>
                </Canvas>
            </Viewbox>
        </Grid>

        <!-- start button -->
        <StackPanel Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">
            <Button x:Name="startButton" FontSize="36" Click="startButton_Click">Start!</Button>
        </StackPanel>
    </Grid>
</Page>

MainPage.xaml.cs中

private void startButton_Click(object sender, RoutedEventArgs e)
{
  double radius = 12;
  double finalAngle = 360;
  double timeStep = 0.004;

  Point initialPoint = new Point(radius + 1, 1);

  // launch animation
  AnimationHelper.AnimatePath(this.progressPath, radius, initialPoint, finalAngle, timeStep, 1);
}

AnimationHelper.cs

public static void AnimatePath(Windows.UI.Xaml.Shapes.Path progressPath, double radius, Point initialPoint, double finalAngle = 180, double timeStep = 0.01, int offset = 0)
{
  var storyboard = new Storyboard();

  var progressAnimation = new ObjectAnimationUsingKeyFrames();
  Storyboard.SetTarget(progressAnimation, progressPath);
  Storyboard.SetTargetProperty(progressAnimation, "(Path.Data)");

  Point center = new Point(radius + offset, radius + offset);
  for (int i = 0; i <= finalAngle; i++)
  {
    var discreteObjectKeyFrame = new DiscreteObjectKeyFrame();
    discreteObjectKeyFrame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(i * timeStep));

    // create points for each ArcSegment
    Point firstArcPoint = new Point(radius, 0);
    Point secondArcPoint = new Point(radius, 0);
    Point calculatedPoint = new Point()
    {
      X = Math.Cos(Math.PI * (270 - i) / 180.0) * radius + center.X,
      Y = Math.Sin(Math.PI * (270 - i) / 180.0) * radius + center.Y
    };

    calculatedPoint.X = -calculatedPoint.X + (radius + offset) * 2 ;

    if (i < 180)
    {
      // use the calculated point for the first and second arc segments
      firstArcPoint = calculatedPoint;
      secondArcPoint = calculatedPoint;
    }
    else
    {
      // leave the first arc segment static and use the calculated point for the second
      firstArcPoint = new Point() { X = radius + offset, Y = radius * 2 + offset };
      secondArcPoint = calculatedPoint;
    }

    // for instance, a complete circle with a radius of 150: "m 150,0 A 150,150 0 0 0 150,300 A 150,150 0 0 0 150,0"
    string dataValue = "m {0},{1} A {2},{2} 0 0 1 {3},{4} A {2},{2} 0 0 1 {5},{6}";
    discreteObjectKeyFrame.Value = string.Format(dataValue, initialPoint.X, initialPoint.Y, radius, firstArcPoint.X, firstArcPoint.Y, secondArcPoint.X, secondArcPoint.Y);
    progressAnimation.KeyFrames.Add(discreteObjectKeyFrame);
  }

  storyboard.Children.Add(progressAnimation);
  storyboard.Begin();
}

1 个答案:

答案 0 :(得分:1)

最后我发现了问题......这太愚蠢了! ergh ...

这是一个简单的string.Format问题。我的示例项目是使用en-US语言环境创建的。但我的真实项目是法语fr-FR

所以 AnimationHelper.cs 中的string.Format的结果

discreteObjectKeyFrame.Value = string.Format(dataValue, initialPoint.X, initialPoint.Y, radius, firstArcPoint.X, firstArcPoint.Y, secondArcPoint.X, secondArcPoint.Y);

/* Correct in en-US (sample)*/
m 13,1 A 12,12 0 0 1 13.2094287872314,1.00182771682739 A 12,12 0 0 1 13.2094287872314,1.00182771682739

/* Wrong in fr-FR due the conversion of double values and so to the comma */
m 13,1 A 12,12 0 0 1 13,2094287872314,1,00182771682739 A 12,12 0 0 1 13,2094287872314,1,00182771682739

所以为了解决我的问题,我只是强迫使用en-US语言环境...

discreteObjectKeyFrame.Value = string.Format(new System.Globalization.CultureInfo("en-US"), dataValue, initialPoint.X, initialPoint.Y, radius, firstArcPoint.X, firstArcPoint.Y, secondArcPoint.X, secondArcPoint.Y);