當 DataObject 的子屬性更改時,我正在嘗試為 DataObject 的 DataTemplate 中的邊框的背景顏色設定影片。DataObject 是一個名為 Test 的類,具有兩個屬性,數字和文本。我有一個名為 Numbers 的 DataObjects 的 ObservableCollection。在任務中,我定期更新 Number 屬性。
<Window
x:Class="WpfAnimationTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfAnimationTest"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
DataContext="{Binding Main, Source={StaticResource Locator}}"
mc:Ignorable="d">
<Grid>
<Grid.Resources>
<DataTemplate x:Key="NumberTemplate">
<TextBlock Text="{Binding NotifyOnTargetUpdated=True}" />
</DataTemplate>
<local:ValueTemplateSelector x:Key="TemplateSelector">
<local:ValueTemplateSelector.NumberTemplate>
<DataTemplate>
<ContentControl Content="{Binding NotifyOnTargetUpdated=True}" ContentTemplate="{StaticResource NumberTemplate}" />
</DataTemplate>
</local:ValueTemplateSelector.NumberTemplate>
</local:ValueTemplateSelector>
<DataTemplate DataType="{x:Type local:Test}">
<Border x:Name="UpdateBorder" Background="Aqua">
<StackPanel Orientation="Horizontal">
<TextBlock
Width="50"
Margin="10"
Text="{Binding Text}" />
<ContentControl
Width="50"
Margin="10"
Content="{Binding Number}"
ContentTemplateSelector="{StaticResource TemplateSelector}" />
<!--
ContentTemplate="{StaticResource NumberTemplate}"
-->
</StackPanel>
</Border>
<DataTemplate.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard AutoReverse="True">
<ColorAnimation
FillBehavior="Stop"
Storyboard.TargetName="UpdateBorder"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#C5AFFFAA"
Duration="00:00:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Grid.Resources>
<ListBox ItemsSource="{Binding Numbers}" />
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace WpfAnimationTest
{
public class Locator
{
public Locator()
{
Main = new Main();
}
public Main Main { get; set; }
}
public class Main
{
public ObservableCollection<Test> Numbers { get; set; } = new ObservableCollection<Test>();
public Main()
{
var rnd = new Random(42);
for (int i = 0; i < 10; i )
{
Numbers.Add(new Test(){Number = i, Text = $"#: {i}"});
}
Task.Run(() =>
{
while (true)
{
try
{
Application.Current?.Dispatcher.Invoke(() =>
{
Numbers[rnd.Next(9)] = new Test
{
Number = rnd.Next(30),
Text = $"# {rnd.Next(30) 30}"
};
});
Thread.Sleep(1000);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
});
}
}
public class Test
{
public int Number { get; set; }
public string Text { get; set; }
}
public class ValueTemplateSelector : DataTemplateSelector
{
/// <summary>
///
/// </summary>
/// <param name="item"></param>
/// <param name="container"></param>
/// <returns></returns>
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
return !(item is Test value)
? null
: NumberTemplate;
}
/// <summary>
///
/// </summary>
public DataTemplate NumberTemplate { get; set; }
/// <summary>
///
/// </summary>
public DataTemplate DefaultTemplate { get; set; }
}
}
當在 ContentControl 中為 Number 屬性使用 ContentTemplate 時,影片正在作業。但是當我使用 ContentTemplateSelector 時,影片不再被觸發。
我在這里想念什么?
uj5u.com熱心網友回復:
您的資料系結錯誤,導致未處理或意外的資料型別。
目前,您的ContentControl.Content
屬性(在DataTemplate
type內Test
)系結到Test.Number
type 的屬性int
。因此,傳遞給 的物件是DataTemplateSelector
typeint
而不是Test
。方法中的條件DataTemplateSelector.SelectTemplate
將回傳 false(原樣int is not Test
)true
并DataTemplateSelector.SelectTemplate
回傳null
- 無模板。XAML 引擎將呼叫實體ToString
,int
因此能夠正確顯示值(盡管缺少 a DataTemplate
)。
解決方案
您必須修復ContentControl.Content
屬性上的系結以系結到Test
實體而不是系結到Test.Number
屬性:
<DataTemplate DataType="{x:Type local:Test}">
<Border x:Name="UpdateBorder"
Background="Aqua">
<StackPanel Orientation="Horizontal">
<TextBlock Width="50"
Margin="10"
Text="{Binding Text}" />
<ContentControl Width="50"
Margin="10"
Content="{Binding}"
ContentTemplateSelector="{StaticResource TemplateSelector}" />
</StackPanel>
</Border>
...
</DataTemplate>
既然DataTemplateSelector
可以正常作業了,還必須調整NumberTemplate
,才能正常顯示Test.Number
屬性。由于我們已經修改了ContentControl.Content
屬性的系結源,新的資料型別現在是Test
(而不是int
):
<DataTemplate x:Key="NumberTemplate"
DataType="{x:Type Test}">
<TextBlock Text="{Binding Number, NotifyOnTargetUpdated=True}" />
</DataTemplate>
評論
這里有很多冗余代碼。DataTemplateSelector
通過洗掉所有模板并正確定義專案的ItemTemplate
,您將獲得相同的結果Test
。
以下大大簡化的版本也應該可以作業:
<Grid>
<Grid.Resources>
<DataTemplate DataType="{x:Type local:Test}">
<Border x:Name="UpdateBorder"
Background="Aqua">
<StackPanel Orientation="Horizontal">
<TextBlock Width="50"
Margin="10"
Text="{Binding Text}" />
<TextBlock Width="50"
Margin="10"
Text="{Binding Number, NotifyOnTargetUpdated=True}" />
</StackPanel>
</Border>
<DataTemplate.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard AutoReverse="True">
<ColorAnimation FillBehavior="Stop"
Storyboard.TargetName="UpdateBorder"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#C5AFFFAA"
Duration="00:00:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Grid.Resources>
<ListBox ItemsSource="{Binding Numbers}" />
</Grid>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/452449.html