簡體   English   中英

帶有 Observablecollection 的 Listview 上的動畫,在 WPF 中對項目進行排序時發生 XamlParseException

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM