2011-01-19 66 views
1

WPF 4アプリケーションがあります。 2つのリストボックスがあります。リストボックスを選択すると、不変オブジェクトをアニメーション化できないエラーが発生する

最初に使用可能な一致のリストがあります。一致が選択されると、その選択は、一致の詳細を表示する詳細グリッドのDataContextとして使用されます。さらに、ストーリーボードが再生され、2番目のリストボックスが表示され、利用可能な市場が表示されます。

これはすべて問題なく動作します。

と、InvalidOperationExceptionた 未処理

アニメーション化することはできません '(0)(1)' に関する :市場は第二リストボックスからアプリのクラッシュを選択し、私が手にしたとき

問題があります不変オブジェクトインスタンス

Markets Listboxはアニメーションを再生しようとしないため、なぜこのようなことが起こっているのかわかりません。マッチリストからの選択を妨害している可能性がありますか? MarketsListで選択が行われたときに詳細データのテキストをリセットしようとしましたが、それは動作しませんでした。聞かせてください

private void ListBoxMatches_SelectionChanged(object sender, SelectionChangedEventArgs e) 
     { 
      if (ListBoxMatches.SelectedIndex != -1) 
      { 
       var selectedMatch = (Match)ListBoxMatches.SelectedItem; 
       if (MatchData.DataContext == null) 
       { 
        MatchData.DataContext = selectedMatch; 
        Storyboard PlayMatch = (Storyboard)FindResource("MatchSelected"); 
        BeginStoryboard(PlayMatch); 
       } 
       else if (MatchData.DataContext != selectedMatch) 
       { 
        MatchData.DataContext = selectedMatch; 
       } 
      } 
     } 

あなたはもう(ストーリーボードのXAMLのような)コードが必要な場合:ここで

これはListBoxMatchesためのSelectionChangedイベントのためのコードである2つのリストボックス

 <StackPanel x:Name="Connected" Grid.Column="1" Grid.Row="1" Visibility="Collapsed"> 
      <ListBox x:Name="ListBoxMatches" HorizontalAlignment="Left" VerticalAlignment="Center" ItemContainerStyle="{DynamicResource ListBoxItemContainerStyle1}" ItemTemplate="{DynamicResource MatchesDataTemplate}" SelectionChanged="ListBoxMatches_SelectionChanged" /> 
     </StackPanel> 

     <Border x:Name="border1" BorderBrush="White" BorderThickness="1" Grid.Row="1" CornerRadius="20" Padding="15" Margin="-400,0,400,0"> 
      <StackPanel x:Name="Markets"> 
       <ListBox x:Name="ListBoxCurrentMarkets" SelectionChanged="ListBoxCurrentMarkets_SelectionChanged" /> 
      </StackPanel> 
     </Border> 

のためのXAMLです私は知っている。

誰もがなぜ、何が起こっているのか知っていれば助けてください。

おかげ

UPDATE

私はダニエルが推奨する変更を行ったが、それは働いていないように私は何か間違ったことを行っている必要があります。 これは私が項目のソースを設定するだけのコードです:

List<Market> TestList = new List<Market>(); 
       Market market = new Market { ID = 0, MarketName = "CorrectScore" }; 
       TestList.Add(market); 
       market = new Market { ID = 1, MarketName = "Match Odds" }; 
       TestList.Add(market);     
       ListBoxCurrentMarkets.ItemsSource = TestList;  

これは、リストボックス

<ListBox x:Name="ListBoxCurrentMarkets" SelectionChanged="ListBoxCurrentMarkets_SelectionChanged" ItemContainerStyle="{DynamicResource ListBoxItemContainerStyle1}"> 
        <ListBox.ItemTemplate> 
         <DataTemplate> 
          <Grid> 
           <TextBlock x:Name="Market" Foreground="Black" TextWrapping="Wrap" Text="{Binding MarketName, Converter={x:Static local:MyCloneConverter.Instance}}" /> 
          </Grid> 
         </DataTemplate> 
        </ListBox.ItemTemplate> 
       </ListBox> 

ためのXAMLであり、これはCloneConverterです:

public class MyCloneConverter : IValueConverter 
    { 
     public static MyCloneConverter Instance = new MyCloneConverter(); 

     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      if (value is Freezable) 
      { 
       value = (value as Freezable).Clone(); 
      } 

      return value; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      throw new NotSupportedException(); 
     } 

    } 

てください見て、あなたの考えを教えてください。私は、値のコンバータにブレークポイントを入れて、ヒットしません。また、リストボックス内の項目は、エラーが発生したことが選択された場合にのみ表示されます。 おかげ

UPDATE

これは、アニメーションのためのXAMLです。アニメーションは、2つのネガティブマージンの境界線を正のマージンに移動します(つまり、画面から画面へ)。 MatchDetails(マッチにバインドされたテキストブロック)を含むボーダーがあり、問題のものは、使用可能なマーケットリストボックスを含むボーダーです。

<Storyboard x:Key="MatchSelected"> 
      <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="borderMatchData"> 
       <EasingThicknessKeyFrame KeyTime="0" Value="0,-400,0,400"/> 
       <EasingThicknessKeyFrame KeyTime="0:0:1" Value="0"/> 
      </ThicknessAnimationUsingKeyFrames> 
      <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="borderMarkets"> 
       <EasingThicknessKeyFrame KeyTime="0" Value="-400,0,400,0"/> 
       <EasingThicknessKeyFrame KeyTime="0:0:1" Value="0"/> 
      </ThicknessAnimationUsingKeyFrames> 
     </Storyboard> 

これはMatchesListBoxためselectionchangedイベントからストーリーボードを再生するためのコードです:

<Border x:Name="borderMarkets" BorderBrush="White" BorderThickness="1" Grid.Row="1" CornerRadius="20" Padding="15" Margin="-400,0,400,0"> 
      <StackPanel x:Name="Markets"> 
       <ListBox x:Name="ListBoxCurrentMarkets" SelectionChanged="ListBoxCurrentMarkets_SelectionChanged" ItemContainerStyle="{DynamicResource ListBoxItemContainerStyle1}"> 
        <ListBox.ItemTemplate> 
         <DataTemplate> 
          <Grid> 
           <TextBlock x:Name="Market" Foreground="Black" TextWrapping="Wrap" Text="{Binding MarketName, Converter={StaticResource CloneConverter}}" /> 
          </Grid> 
         </DataTemplate> 
        </ListBox.ItemTemplate> 
       </ListBox> 
      </StackPanel> 
     </Border> 

がUPDATE

MatchData.DataContext = selectedMatch; 
        Storyboard PlayMatch = (Storyboard)FindResource("MatchSelected"); 
        BeginStoryboard(PlayMatch); 

これはBorderMArketsのためのXAMLです

これはカウあなたがデータバインドされたプロパティをアニメーション化する場合は、すべての問題(と思う)

<ControlTemplate x:Key="ListBoxItemControlTemplate1" TargetType="{x:Type ListBoxItem}"> 
     <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true" Background="#FF807F7F"> 
      <VisualStateManager.VisualStateGroups> 
       <VisualStateGroup x:Name="CommonStates"> 
        <VisualState x:Name="Normal"/> 
        <VisualState x:Name="MouseOver"> 
         <Storyboard> 
          <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="Bd"> 
           <EasingColorKeyFrame KeyTime="0" Value="#FF3D3B3B"/> 
          </ColorAnimationUsingKeyFrames> 
         </Storyboard> 
        </VisualState> 
        <VisualState x:Name="Disabled"/> 
       </VisualStateGroup> 
       <VisualStateGroup x:Name="SelectionStates"> 
        <VisualState x:Name="Unselected"/> 
        <VisualState x:Name="Selected"> 
         <Storyboard> 
          <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="Bd"> 
           <EasingColorKeyFrame KeyTime="0" Value="#FFA71616"/> 
          </ColorAnimationUsingKeyFrames> 
         </Storyboard> 
        </VisualState> 
        <VisualState x:Name="SelectedUnfocused"> 
         <Storyboard> 
          <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="Bd"> 
           <EasingColorKeyFrame KeyTime="0" Value="#FFA71616"/> 
          </ColorAnimationUsingKeyFrames> 
         </Storyboard> 
        </VisualState> 
       </VisualStateGroup> 
       <VisualStateGroup x:Name="FocusStates"> 
        <VisualState x:Name="Unfocused"/> 
        <VisualState x:Name="Focused"> 
         <Storyboard> 
          <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="Bd"> 
           <EasingColorKeyFrame KeyTime="0" Value="#FF18E526"/> 
          </ColorAnimationUsingKeyFrames> 
         </Storyboard> 
        </VisualState> 
       </VisualStateGroup> 
      </VisualStateManager.VisualStateGroups> 
      <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
     </Border> 
     <ControlTemplate.Triggers> 
      <Trigger Property="IsSelected" Value="true"> 
       <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> 
       <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/> 
      </Trigger> 
      <MultiTrigger> 
       <MultiTrigger.Conditions> 
        <Condition Property="IsSelected" Value="true"/> 
        <Condition Property="Selector.IsSelectionActive" Value="false"/> 
       </MultiTrigger.Conditions> 
       <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> 
       <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 
      </MultiTrigger> 
      <Trigger Property="IsEnabled" Value="false"> 
       <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> 
      </Trigger> 
     </ControlTemplate.Triggers> 
    </ControlTemplate> 

答えて

3

http://blogs.msdn.com/b/mikehillberg/archive/2006/09/26/cannotanimateimmutableobjectinstance.aspx

を参照してください歌う基本的に、これが起こります。

+0

これはアニメーションとバインドを同時に行うためですアニメーションの後にListBoxアイテムのソースを適用すると、それは機能しますか? – Chris

+0

これは役に立たないと思います。この記事で紹介するソリューションを使用する必要があります。つまり、フリーズ可能オブジェクトのクローンを返すIValueConverterを指定する必要があります。この例の 'MyCloneConverter'クラスもうまくいくはずです。 –

+0

ダニエル私はそれを試してみましたが、うまくいきません。私は何が間違っているのか分かりません。私は更新されたコードを投稿します。見てください。 – Chris

関連する問題