我试图在鼠标悬停时更改Path控件的颜色,其中路径数据始终通过数据绑定进行更改。它应该从黄色变为红色,但是当我将鼠标移到路径上时,路径上没有颜色变化,它仍然是黄色。
我的观点:
MainWindow.xaml
<reactiveui:ReactiveWindow
x:Class="TestWpfAnim.MainWindow"
x:TypeArguments="local:MainViewModel"
xmlns:reactiveui="http://reactiveui.net"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestWpfAnim"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:PointsToPathNormalConv x:Key="MyConv" />
</Window.Resources>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<!--Take one half second to transition to the MouseOver state.-->
<VisualTransition To="MouseOver" GeneratedDuration="0:0:0.5" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="MyAnimatedBrush" Storyboard.TargetProperty="Color" To="Red" Duration="0:0:0.5"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Path
x:Name="MainPath" StrokeThickness="4"
Data="{Binding Poly, Converter={StaticResource MyConv}}">
<Path.Stroke>
<SolidColorBrush Color="Yellow" x:Name="MyAnimatedBrush" />
</Path.Stroke>
</Path>
</Grid>
MainWindow.xaml.cs
public partial class MainWindow : ReactiveWindow<MainViewModel>
{
public MainWindow()
{
InitializeComponent();
ViewModel = new MainViewModel();
DataContext = ViewModel;
var timer = new DispatcherTimer(DispatcherPriority.Normal, Dispatcher.CurrentDispatcher)
{
Interval = TimeSpan.FromSeconds(2)
};
int x = 100;
int y = 100;
timer.Tick += (o, e) =>
{
ViewModel.Add(x++, y++ * 2);
};
timer.Start();
}
}
转换器
[ValueConversion(typeof(IEnumerable<System.Windows.Point>), typeof(Geometry))]
public class PointsToPathNormalConv : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is IEnumerable<System.Windows.Point> points && points.Any())
{
List<LineSegment> segments = new List<LineSegment>();
foreach (var p in points)
{
segments.Add(new LineSegment(p, true));
}
PathFigure figure = new PathFigure(points.First(), segments, false); //true if closed
PathGeometry geometry = new PathGeometry();
geometry.Figures.Add(figure);
return geometry;
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
我的视图模型: MainViewModel.cs
public class MainViewModel : AbstractNotifyPropertyChanged, IDisposable
{
public MainViewModel()
{
Poly = new ObservableCollection<System.Windows.Point>();
}
public void Add(int x, int y)
{
var newlist = Poly.ToList();
newlist.Add(new System.Windows.Point(x, y));
Poly = new ObservableCollection<System.Windows.Point>(newlist);
}
public void Dispose()
{
}
private ObservableCollection<System.Windows.Point> _poly;
public ObservableCollection<System.Windows.Point> Poly
{
get => _poly;
set => this.SetAndRaise(ref _poly, value);
}
}
答案 0 :(得分:1)
根据documentation,仅由于名称为“ MouseOver”,就无法触发VisualTransition。它仍然需要某种事件处理程序来执行过渡。您必须为Path触发的MouseOver事件添加一个事件处理程序。
答案 1 :(得分:0)
我看到我的错误是基于我最初从中学到的使用VisualStateManager的各种来源对已有的视觉状态名称进行假设。
将以下代码添加到我的视图中可以正常工作:
MainWindow.xaml.cs
public void Path_MouseEnter(object sender, MouseEventArgs e)
{
if (sender is FrameworkElement fe)
VisualStateManager.GoToElementState(fe, "MouseEnter", true);
}
public void Path_MouseLeave(object sender, MouseEventArgs e)
{
if (sender is FrameworkElement fe)
VisualStateManager.GoToElementState(fe, "MouseLeave", true);
}
MainWindow.xaml
将状态管理器代码移到 Path 元素中。在将更改状态的路径上指定 MouseEnter 和 MouseLeave 操作。
<Path
x:Name="MainPath" StrokeThickness="4"
Data="{Binding Poly, Converter={StaticResource MyConv}}"
MouseEnter="Path_MouseEnter"
MouseLeave="Path_MouseLeave">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="MouseLeave"/>
<VisualState x:Name="MouseEnter">
<Storyboard>
<ColorAnimation Storyboard.TargetName="MyAnimatedBrush" Storyboard.TargetProperty="Color" To="Red" Duration="0:0:0.5"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Path.Stroke>
<SolidColorBrush Color="Yellow" x:Name="MyAnimatedBrush" />
</Path.Stroke>
</Path>