在数据模板中,在 MouseMove 时更新图像源(视频缩略图)
Within datatemplate, update Image source when MouseMove (video thumbnails)
我想在触发 MouseMove
事件时更新 Image
的来源:
<DataTemplate>
...
<Viewbox MaxWidth="100" MaxHeight="100" >
<Image x:Name="Vignette0" Source="{Binding Vignette}" MouseMove="Vignette0_OnMouseMove"/>
</Viewbox>
</DataTemplate>
[2]
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding xxxx}" Value="true">
<Setter Property="Source" Value="{Binding Vignette}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
其中 Vignette
是 属性 通知更改。
- 我尝试 [2] 用
style.triggers
(Change image using trigger WPF MVVM) 计算一些东西,但在我的例子中,源是动态绑定 (datatemplate)
- 我无法将
MouseMove
放在 Binding
at xxxx
- 我也尝试用代码隐藏做点什么,但我想不通。
有人有想法吗?
原始 XAML 代码:
<DataGrid x:Name="DgTest" ItemsSource="{Binding Evm.RawImagesCollectionView}" AutoGenerateColumns="false"
SelectedItem="{Binding Evm.SelectedImage}">
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=ParentDir}" />
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander>
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=ParentDir}" />
<TextBlock Text="{Binding Path=ItemCount}"/>
<TextBlock Text=" images"/>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True"/>
<DataGridTextColumn Header="#frames" Binding="{Binding NumberOfFrames}" IsReadOnly="True"/>
<DataGridTextColumn Header="#bg" Binding="{Binding NumberOfBackgrounds}" IsReadOnly="True"/>
<DataGridTextColumn Header="path" Binding="{Binding ParentDir}" IsReadOnly="True"/>
<DataGridTemplateColumn Header="action">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="vertical" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal">
<Button Content="prepare" Command="{Binding DecodeCommand}" Height="24"/>
<ProgressBar Minimum="0" Maximum="1.00" Value="{Binding PercentDone}" Width="40" Height="24"/>
</StackPanel>
<Viewbox MaxWidth="100" MaxHeight="100" >
<Image x:Name="VignetteViewBox0" Source="{Binding Vignette}" MouseMove="VignetteViewBox0_OnMouseMove">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding }" Value="true">
<Setter Property="Source" Value="{Binding Vignette}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Viewbox>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
属性 Vignette
:
public BitmapImage Vignette
{
get
{
if (NumberOfFrames > 0)
{
var files = Directory.GetFiles(Filedir, "out*");
if (files.Length >= 5)
VignetteNumber = VignetteNumber != 5 ? 5 : _rgen.Next(0, files.Length);
else
VignetteNumber = _rgen.Next(0, files.Length);
var filepath = files[VignetteNumber];
var buffer = new BitmapImage();
using (Stream imageStreamSource = new FileStream(filepath,
FileMode.Open, FileAccess.Read, FileShare.Read))
{
buffer.BeginInit();
buffer.CacheOption = BitmapCacheOption.OnLoad;
buffer.StreamSource = imageStreamSource;
buffer.EndInit();
}
return buffer;
}
return null;
}
}
这是您尝试实现的功能的工作示例。
确保更改视图模型中的常量以引用您有一些 BMP 用于测试的目录。
祝你有美好的一天:)
MainWindow.xaml
<Window x:Class="WpfApplication13.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication13"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" d:DataContext="{d:DesignInstance local:VmMainWindow, IsDesignTimeCreatable=True}">
<Grid>
<DataGrid x:Name="dataGrid" ItemsSource="{Binding Items}" AutoGenerateColumns="false">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True" Width="150"/>
<DataGridTemplateColumn Header="BMP" Width="150" IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="local:VmItemInGrid">
<Viewbox MaxWidth="100" MaxHeight="100">
<Image Source="{Binding BMP}" MouseEnter="Image_MouseEnter" />
</Viewbox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
MainWindow.xaml.cs(代码隐藏)
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WpfApplication13
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new VmMainWindow();
}
private void Image_MouseEnter(object sender, MouseEventArgs e)
{
((VmItemInGrid)((Image)sender).DataContext).GetNextFile();
}
}
}
视图模型部件
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Windows.Media.Imaging;
namespace WpfApplication13
{
public class VmMainWindow : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public List<VmItemInGrid> Items { get; }
public VmMainWindow()
{
Items = new List<VmItemInGrid>
{
new VmItemInGrid {Name = "Item1"},
new VmItemInGrid {Name = "Item2"},
new VmItemInGrid {Name = "Item3"}
};
}
}
public class VmItemInGrid : INotifyPropertyChanged
{
private const string generalBmpPath = @"C:\Users\Gil\Pictures\TestBMPs\";
public event PropertyChangedEventHandler PropertyChanged;
private string filepath;
public VmItemInGrid()
{
GetNextFile();
}
public string Name { get; set; }
public BitmapImage BMP
{
get
{
var buffer = new BitmapImage();
using (Stream imageStreamSource = new FileStream(filepath,
FileMode.Open, FileAccess.Read, FileShare.Read))
{
buffer.BeginInit();
buffer.CacheOption = BitmapCacheOption.OnLoad;
buffer.StreamSource = imageStreamSource;
buffer.EndInit();
}
return buffer;
}
}
public void GetNextFile()
{
var allFiles = Directory.GetFiles(generalBmpPath, "*.bmp");
var random = new Random();
var index = random.Next(allFiles.Length);
filepath = allFiles[index];
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(BMP)));
}
}
}
我想在触发 MouseMove
事件时更新 Image
的来源:
<DataTemplate>
...
<Viewbox MaxWidth="100" MaxHeight="100" >
<Image x:Name="Vignette0" Source="{Binding Vignette}" MouseMove="Vignette0_OnMouseMove"/>
</Viewbox>
</DataTemplate>
[2]
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding xxxx}" Value="true">
<Setter Property="Source" Value="{Binding Vignette}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
其中 Vignette
是 属性 通知更改。
- 我尝试 [2] 用
style.triggers
(Change image using trigger WPF MVVM) 计算一些东西,但在我的例子中,源是动态绑定 (datatemplate) - 我无法将
MouseMove
放在Binding
at xxxx - 我也尝试用代码隐藏做点什么,但我想不通。
有人有想法吗?
原始 XAML 代码:
<DataGrid x:Name="DgTest" ItemsSource="{Binding Evm.RawImagesCollectionView}" AutoGenerateColumns="false"
SelectedItem="{Binding Evm.SelectedImage}">
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=ParentDir}" />
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander>
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=ParentDir}" />
<TextBlock Text="{Binding Path=ItemCount}"/>
<TextBlock Text=" images"/>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True"/>
<DataGridTextColumn Header="#frames" Binding="{Binding NumberOfFrames}" IsReadOnly="True"/>
<DataGridTextColumn Header="#bg" Binding="{Binding NumberOfBackgrounds}" IsReadOnly="True"/>
<DataGridTextColumn Header="path" Binding="{Binding ParentDir}" IsReadOnly="True"/>
<DataGridTemplateColumn Header="action">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="vertical" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal">
<Button Content="prepare" Command="{Binding DecodeCommand}" Height="24"/>
<ProgressBar Minimum="0" Maximum="1.00" Value="{Binding PercentDone}" Width="40" Height="24"/>
</StackPanel>
<Viewbox MaxWidth="100" MaxHeight="100" >
<Image x:Name="VignetteViewBox0" Source="{Binding Vignette}" MouseMove="VignetteViewBox0_OnMouseMove">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding }" Value="true">
<Setter Property="Source" Value="{Binding Vignette}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Viewbox>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
属性 Vignette
:
public BitmapImage Vignette
{
get
{
if (NumberOfFrames > 0)
{
var files = Directory.GetFiles(Filedir, "out*");
if (files.Length >= 5)
VignetteNumber = VignetteNumber != 5 ? 5 : _rgen.Next(0, files.Length);
else
VignetteNumber = _rgen.Next(0, files.Length);
var filepath = files[VignetteNumber];
var buffer = new BitmapImage();
using (Stream imageStreamSource = new FileStream(filepath,
FileMode.Open, FileAccess.Read, FileShare.Read))
{
buffer.BeginInit();
buffer.CacheOption = BitmapCacheOption.OnLoad;
buffer.StreamSource = imageStreamSource;
buffer.EndInit();
}
return buffer;
}
return null;
}
}
这是您尝试实现的功能的工作示例。
确保更改视图模型中的常量以引用您有一些 BMP 用于测试的目录。
祝你有美好的一天:)
MainWindow.xaml
<Window x:Class="WpfApplication13.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication13"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" d:DataContext="{d:DesignInstance local:VmMainWindow, IsDesignTimeCreatable=True}">
<Grid>
<DataGrid x:Name="dataGrid" ItemsSource="{Binding Items}" AutoGenerateColumns="false">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True" Width="150"/>
<DataGridTemplateColumn Header="BMP" Width="150" IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="local:VmItemInGrid">
<Viewbox MaxWidth="100" MaxHeight="100">
<Image Source="{Binding BMP}" MouseEnter="Image_MouseEnter" />
</Viewbox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
MainWindow.xaml.cs(代码隐藏)
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WpfApplication13
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new VmMainWindow();
}
private void Image_MouseEnter(object sender, MouseEventArgs e)
{
((VmItemInGrid)((Image)sender).DataContext).GetNextFile();
}
}
}
视图模型部件
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Windows.Media.Imaging;
namespace WpfApplication13
{
public class VmMainWindow : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public List<VmItemInGrid> Items { get; }
public VmMainWindow()
{
Items = new List<VmItemInGrid>
{
new VmItemInGrid {Name = "Item1"},
new VmItemInGrid {Name = "Item2"},
new VmItemInGrid {Name = "Item3"}
};
}
}
public class VmItemInGrid : INotifyPropertyChanged
{
private const string generalBmpPath = @"C:\Users\Gil\Pictures\TestBMPs\";
public event PropertyChangedEventHandler PropertyChanged;
private string filepath;
public VmItemInGrid()
{
GetNextFile();
}
public string Name { get; set; }
public BitmapImage BMP
{
get
{
var buffer = new BitmapImage();
using (Stream imageStreamSource = new FileStream(filepath,
FileMode.Open, FileAccess.Read, FileShare.Read))
{
buffer.BeginInit();
buffer.CacheOption = BitmapCacheOption.OnLoad;
buffer.StreamSource = imageStreamSource;
buffer.EndInit();
}
return buffer;
}
}
public void GetNextFile()
{
var allFiles = Directory.GetFiles(generalBmpPath, "*.bmp");
var random = new Random();
var index = random.Next(allFiles.Length);
filepath = allFiles[index];
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(BMP)));
}
}
}