列表框选择会产生“无法对不可变对象进行动画处理”错误
我有一个 WPF 4 应用程序。它包含 2 个列表框。
第一个有可用匹配的列表。当选择匹配项时,该选择将用作显示匹配项详细信息的详细信息网格的 DataContext。此外,还会播放故事板,并显示第二个列表框,显示可用市场。
这一切都很好。
问题是,当从第二个列表框中选择市场时,应用程序崩溃,我得到:
InvalidOperationException 是 未处理
无法为“(0).(1)”设置动画 不可变对象实例
我不知道为什么会发生这种情况,因为市场列表框不会尝试播放任何动画。会不会干扰比赛名单的选择? 我尝试在 MarketsList 中进行选择时重置详细信息数据上下文,但这不起作用。
这是两个 ListBoxes 的 xaml
<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>
这是 ListBoxMatches 的 SelectionChanged 事件的代码:
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),请告诉我。
如果有人知道为什么以及发生了什么事,请帮忙。
谢谢
更新,
我做了丹尼尔建议的更改,但我一定做错了什么,因为它不起作用。 这是我设置项目源的代码:
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;
这是列表框的 xaml
<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>
,这是 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();
}
}
请看一下并告诉我您的想法?我在 valueconverter 中放置了一个断点,但它没有被击中。此外,列表框中的项目也会显示,只有在进行选择时才会发生错误。 谢谢
更新
这是动画的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 的选择更改事件中播放故事板的代码:
MatchData.DataContext = selectedMatch;
Storyboard PlayMatch = (Storyboard)FindResource("MatchSelected");
BeginStoryboard(PlayMatch);
这是 BorderMArkets 的 xaml:
<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>
更新
这是导致所有问题的模板(我认为)
<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>
I have a WPF 4 application. It contains 2 listboxes.
The first has a list of available matches. when a match is selected the selection is used as the DataContext for a details grid displaying details of the match. Additionally a storyboard is played and the 2nd Listbox comes into view displaying the available markets.
This all works fine.
Problem is when a market is selected from the 2nd listbox the app crashes and I get :
InvalidOperationException was
unhandledCannot animate '(0).(1)' on
an immutable object instance
I don't know why this is happening since the Markets Listbox doesn't try to play any animation. Could it be interfering with the selection from the match list??
I tried resetting the details datacontext when a selection is made in the MarketsList but that didnt work.
Here's the xaml for the two ListBoxes
<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>
This is the code for the SelectionChanged event for the ListBoxMatches:
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;
}
}
}
If you need anymore code(like the storyboard xaml) please let me know.
If anyone knows why and whats going on please help.
Thanks
UPDATE
I made the change recommended by Daniel but I must have done something wrong as it's not working.
This is the code just where I set the items source:
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;
This is the xaml for the listbox
<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>
and this is the 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();
}
}
Please take a look and tell me what you think? I put a breakpoint in the valueconverter and it's not getting hit. Also the item's in the listbox are showing up it's only when a selection is made that the error occurs.
Thanks
UPDATE
This is the xaml for the animation. The animation moves 2 negatively margined borders into positive margin(ie from out of screen into screen). There is a border which contains MatchDetails(textblocks databound to a Match), the one in question is a Border which contains the available markets ListBox.
<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>
This is the code for playing the storyboard from the selectionchanged event for the MatchesListBox:
MatchData.DataContext = selectedMatch;
Storyboard PlayMatch = (Storyboard)FindResource("MatchSelected");
BeginStoryboard(PlayMatch);
This is the xaml for the BorderMArkets:
<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
This is the template that was causing all the problems(I think)
<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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
请参阅 http://blogs.msdn.com/b/ mikehillberg/archive/2006/09/26/cannotanimateimmutableobjectinstance.aspx
基本上,如果您对数据绑定属性进行动画处理,就会发生这种情况。
See http://blogs.msdn.com/b/mikehillberg/archive/2006/09/26/cannotanimateimmutableobjectinstance.aspx
Basically, this happens if you animate a databound property.