[英]Animation on Listview with Observablecollection, XamlParseException occured when sort items in WPF
當我在Listview
上使用 Animation 時,我遇到了cannot found property Background.Opacity
。
看我的GIF。 下圖顯示了我目前的工作狀態。
我收到一條錯誤消息,指出 - 找不到屬性Backgorund.Opactiy
。 我認為這很奇怪,因為它在我排序之前有效。
先看看我的 xaml 源代碼。
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition />
</Grid.RowDefinitions>
<ListView ItemsSource="{Binding bsources}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel.Style>
<Style TargetType="{x:Type StackPanel}">
<Style.Triggers>
<DataTrigger Binding="{Binding Checked}" Value="True">
<Setter Property="Background">
<Setter.Value>
<DrawingBrush
x:Name="errorBrush"
TileMode="Tile"
Viewport="0 0 1 1"
ViewportUnits="Absolute">
<DrawingBrush.RelativeTransform>
<RotateTransform Angle="45" />
</DrawingBrush.RelativeTransform>
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<LineGeometry StartPoint="0,0" EndPoint="4,2" />
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="Red" Thickness="4" />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Setter.Value>
</Setter>
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<!-- Storyboard.TargetProperty = "opacity" throws no error -->
<DoubleAnimationUsingKeyFrames
FillBehavior="Stop"
Storyboard.TargetProperty="Background.Opacity"
Duration="0:0:1">
<LinearDoubleKeyFrame KeyTime="0:0:0.0" Value="0.2" />
<LinearDoubleKeyFrame KeyTime="0:0:0.3" Value="0.3" />
<LinearDoubleKeyFrame KeyTime="0:0:0.5" Value="0.8" />
<LinearDoubleKeyFrame KeyTime="0:0:1" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<CheckBox IsChecked="{Binding Checked}" />
<TextBlock Margin="20,0,0,0" Text="{Binding Name}" />
<TextBlock Margin="20,0,0,0" Text="{Binding Address}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button
Name="Sort"
Grid.Row="2"
Click="Sort_Click"
Content="Sort" />
</Grid>
列表視圖具有項目來源。 如果 item 的 Property Checked
為 true,則它開始storyboard
並將其背景設為紅色drawingbrush
。 我認為這個錯誤很奇怪的原因是當我單擊一個項目並使Checked
Property 為 true 時它工作得很好。 但是當我對ObservableCollection
排序並分配new ObservableCollection
它會引發錯誤。 ...
在 xaml 代碼中,請參閱我的評論。 在 Lines 那里,我嘗試不使用Background
前綴。 Storyboard.TargetProperty="Opacity"
然后它起作用了。 見下圖。
您可以告知第一張圖片和第二張圖片之間的差異,但讓我向您解釋差異。 第一個只更改其背景畫筆不透明度,但第二個更改所有內容(包括文本)的不透明度。 我想在沒有任何錯誤的情況下實現第一個動畫。
感謝您的閱讀。
我認為 csharp 代碼沒有問題 - 但我也會發布我的源代碼。 以下來源是我的 csharp 來源。
public partial class MainWindow : Window, INotifyPropertyChanged
{
bool state = false;
private ObservableCollection<Person> _bSources;
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChagned([CallerMemberName] string name = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
public ObservableCollection<Person> bsources
{
get { return _bSources; }
set { _bSources = value; OnPropertyChagned(); }
}
public MainWindow()
{
bsources = new ObservableCollection<Person>
{ new Person("김", "부산"), new Person("정", "강원도"), new Person("최", "서울"), new Person("권", "전라도"), new Person("박", "대전") };
InitializeComponent();
DataContext = this;
}
private void Sort_Click(object sender, RoutedEventArgs e)
{
if (state)
{
bsources = new ObservableCollection<Person>(bsources.OrderBy(i => i.Checked));
state = false;
}
else
{
bsources = new ObservableCollection<Person>(bsources.OrderByDescending(i => i.Checked));
state = true;
}
}
}
public class Person : INotifyPropertyChanged
{
private bool _Checked;
public bool Checked
{
get { return _Checked; }
set { _Checked = value; OnPropertyChagned(); }
}
private string name;
public string Name
{
get { return name; }
set { name = value; OnPropertyChagned(); }
}
private string _Address;
public string Address
{
get { return _Address; }
set { _Address = value; OnPropertyChagned(); }
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChagned([CallerMemberName] string name=null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
public Person(string name, string Address)
{
this.Checked = false;
this.Name = name;
this.Address = Address;
}
}
為更新HasError
屬性添加了按鈕, HasError
屬性只是檢查checkbox
是否被選中。
以下是我的 xaml 代碼,與原始 xaml 源代碼變化不大。 現在DataTrigger
Binding 屬性是HasError
並且 DataTrigger.EnterAction 更改為DataTrigger.ExitAction
。 在該堆棧面板下方,我添加了新按鈕來更新 Person 類屬性的HasError
。
<ListView ItemsSource="{Binding bsources}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel.Style>
<Style TargetType="{x:Type StackPanel}">
<Style.Triggers>
<DataTrigger Binding="{Binding HasError}" Value="True">
<Setter Property="Background">
<Setter.Value>
<DrawingBrush
x:Name="errorBrush"
TileMode="Tile"
Viewport="0 0 1 1"
ViewportUnits="Absolute">
<DrawingBrush.RelativeTransform>
<RotateTransform Angle="45" />
</DrawingBrush.RelativeTransform>
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<LineGeometry StartPoint="0,0" EndPoint="4,2" />
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="Red" Thickness="4" />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Setter.Value>
</Setter>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
FillBehavior="Stop"
Storyboard.TargetProperty="Background.Opacity"
Duration="0:0:1">
<LinearDoubleKeyFrame KeyTime="0:0:0.0" Value="0.2" />
<LinearDoubleKeyFrame KeyTime="0:0:0.3" Value="0.3" />
<LinearDoubleKeyFrame KeyTime="0:0:0.5" Value="0.8" />
<LinearDoubleKeyFrame KeyTime="0:0:1" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<CheckBox IsChecked="{Binding Checked}" />
<TextBlock Margin="20,0,0,0" Text="{Binding Name}" />
<TextBlock Margin="20,0,0,0" Text="{Binding Address}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button
Name="UpdateAnimation"
Grid.Row="1"
Click="UpdateAnimation_Click"
Content="Update Animation" />
//in class Mainwindow
private void UpdateAnimation_Click(object sender, RoutedEventArgs e)
{
// update HasError
foreach( Person p in bsources)
p.HasError = p.Checked;
}
//in Person Class
/// <summary>
/// added
/// </summary>
private bool _HasError;
public bool HasError
{
get { return _HasError; }
set { _HasError = value; OnPropertyChagned(); }
}
以下 gif 顯示錯誤消息。
最后一個例外,您可能會忽略它。 我通過添加以下 xaml 源來解決。
<DataTrigger Binding="{Binding HasError}" Value="false">
<Setter Property="Background">
<Setter.Value>
<DrawingBrush Opacity="0" />
</Setter.Value>
</Setter>
</DataTrigger>
但如您所見,在 Gif 中,沒有不透明度增量更改。 ……嗚咽……
簡而言之, DataTrigger.ExitActions
沒有增加不透明度變化。
我相信問題在於當您分配 ObservableCollection 的新實例時,尚未呈現 Stackpanel(帶有動畫的 DrawingBrush 背景)。 甚至在呈現 StackPanel 背景之前,首先觸發 DataTrigger EnterAction。 在這個假設下,我設法只能通過改變DataTrigger.EnterActions到DataTrigger.ExitActions,讓您排序工作。 我還需要添加一個后備默認 DrawingBrush,以防您刪除檢查。 在更新的樣式下方:
<Style TargetType="{x:Type StackPanel}">
<Style.Setters>
<Setter Property="Background">
<Setter.Value>
<DrawingBrush />
<!--A default drawing brush-->
</Setter.Value>
</Setter>
</Style.Setters>
<Style.Triggers>
<DataTrigger Binding="{Binding Checked}"
Value="True">
<Setter Property="Background">
<Setter.Value>
<DrawingBrush x:Name="errorBrush"
TileMode="Tile"
Viewport="0 0 1 1"
ViewportUnits="Absolute">
<DrawingBrush.RelativeTransform>
<RotateTransform Angle="45" />
</DrawingBrush.RelativeTransform>
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<LineGeometry StartPoint="0,0"
EndPoint="4,2" />
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="Red"
Thickness="4" />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Setter.Value>
</Setter>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<!-- Storyboard.TargetProperty = "opacity" throws no error -->
<DoubleAnimationUsingKeyFrames FillBehavior="Stop"
Storyboard.TargetProperty="Background.Opacity"
Duration="0:0:1">
<LinearDoubleKeyFrame KeyTime="0:0:0.0"
Value="0.2" />
<LinearDoubleKeyFrame KeyTime="0:0:0.3"
Value="0.3" />
<LinearDoubleKeyFrame KeyTime="0:0:0.5"
Value="0.8" />
<LinearDoubleKeyFrame KeyTime="0:0:1"
Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
更新的答案這就是我如何通過 HasError 使您更新的問題起作用。 請試一試:
<ListView ItemsSource="{Binding bsources}">
<ListView.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<DrawingBrush x:Key="DB" Opacity="0" TileMode="Tile" Viewport="0 0 1 1" ViewportUnits="Absolute">
<DrawingBrush.RelativeTransform>
<RotateTransform Angle="45" />
</DrawingBrush.RelativeTransform>
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<LineGeometry StartPoint="0,0" EndPoint="4,2" />
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="Red" Thickness="4" />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</DataTemplate.Resources>
<StackPanel Orientation="Horizontal">
<StackPanel.Style>
<Style TargetType="{x:Type StackPanel}">
<Style.Setters>
<Setter Property="Background" Value="{StaticResource DB}"/>
</Style.Setters>
<Style.Triggers>
<DataTrigger Binding="{Binding HasError}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
FillBehavior="HoldEnd"
Storyboard.TargetProperty="Background.Opacity"
Duration="0:0:1">
<LinearDoubleKeyFrame KeyTime="0:0:0.0" Value="0.2" />
<LinearDoubleKeyFrame KeyTime="0:0:0.3" Value="0.3" />
<LinearDoubleKeyFrame KeyTime="0:0:0.5" Value="0.8" />
<LinearDoubleKeyFrame KeyTime="0:0:1" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding HasError}" Value="false">
<Setter Property="Background">
<Setter.Value>
<DrawingBrush Opacity="0" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<CheckBox IsChecked="{Binding Checked}" />
<TextBlock Margin="20,0,0,0" Text="{Binding Name}" />
<TextBlock Margin="20,0,0,0" Text="{Binding Address}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.