C# 使用WPF如何在某些情况下使用绑定对图像进行灰度化
该应用程序是一个messenger,我正在其中使用microsoft lync client进行此操作。在其中一个上下文中,我在listview中获取联系人(LyncClient的对象,具有名称、图像、可用性等属性),并将其加载到数据模板中,该数据模板定义如下:C# 使用WPF如何在某些情况下使用绑定对图像进行灰度化,c#,wpf,data-binding,binding,converter,C#,Wpf,Data Binding,Binding,Converter,该应用程序是一个messenger,我正在其中使用microsoft lync client进行此操作。在其中一个上下文中,我在listview中获取联系人(LyncClient的对象,具有名称、图像、可用性等属性),并将其加载到数据模板中,该数据模板定义如下: <DataTemplate x:Key="ContactsTemplate"> <Grid HorizontalAlignment="Left" Width="150" Height="150" Mar
<DataTemplate x:Key="ContactsTemplate">
<Grid HorizontalAlignment="Left" Width="150" Height="150" Margin="10">
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
<Image Source="{Binding Image}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
</Border>
<StackPanel VerticalAlignment="Bottom" Background="{Binding Availability, Converter={StaticResource AvailabilityToPresenceColor}}" Opacity="0.75">
<TextBlock Text="{Binding Name}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="20" Margin="15,0,15,15"/>
</StackPanel>
</Grid>
</DataTemplate>
现在的问题是,我有一个grayBitmapSource,它的类型是FormatConvertedBitmap,我不知道如何再次将其转换为Stream。我建议阅读这篇关于WPF中图像处理的文章: 使用图像处理逻辑,可以为每个可用性状态创建不同的图片。您可以使用IValueConverter,但这意味着您必须在每次可用性状态更改时重新处理映像。相反,您可以简单地更改Contact类,这样当您更改Availability属性时,它会自动向WPF发送信号,以获取图像属性引用的图片:
public class Contact : INotifyPropertyChanged
{
// EDIT: INotifyPropertyChanged implementation.
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
// EDIT: INotifyPropertyChanged implementation.
private ContactAvailability _Availability;
public ContactAvailability Availability
{
get { return _Availability; }
set
{
_Availability = value;
NotifyPropertyChanged("Availability");
NotifyPropertyChanged("Image");
}
}
public BitmapImage _AvailablePicture;
public BitmapImage _BusyPicture;
public BitmapImage Image
{
get
{
switch (this.Availability)
{
case ContactAvailability.Available:
return this._AvailablePicture;
case ContactAvailability.Busy:
return this._BusyPicture;
default:
throw new NotImplementedException();
}
}
}
}
编辑(评论太长):
我添加了代码来实现INotifyPropertyChanged
接口。这在WPF中非常常见,所以我认为您已经熟悉这种方法了
在您的示例中,Image.Source
是一个DepencyProperty
。当类实现INotifyPropertyChanged时,您可以告诉WPF它的一个属性已更改。您只需使用更改的属性名称引发NotifyPropertyChanged
事件。这会通知WPF更新绑定到给定属性的所有DepencyProperty
s
在图像处理方面,这与绑定有什么不同。我的意思是,每次可用性发生变化时,也应该以这种方式执行图像处理代码。我说的对不对@bouvierr
不会。在这种情况下,我们只执行固定次数的图像处理,为每个可用状态创建图片(在我的示例中,每个联系人2次)。例如,我们可以在应用程序启动期间创建所有图片(3个联系人x 2个状态=6个图片),并将它们存储在每个联系人的\u AvailablePicture
和\u BusyPicture
字段中
这里是重要的部分:当我们设置可用性
属性时,我们还调用NotifyPropertyChanged(“Image”)
。这将强制WPF更新Image.Source
DepencyProperty
,因为它绑定到Contact.Image
。这将返回不同的图片,因为可用性已更改
在我的示例中,我决定存储图片。这可能不是您的最佳解决方案。它消耗更多内存,但节省处理时间。如果希望在每次可用性状态更改时重新处理映像,则应将Contact.Image
属性更改为类似以下内容:
public BitmapImage Image
{
get
{
switch (this.Availability)
{
case ContactAvailability.Available:
return this._AvailablePicture;
case ContactAvailability.Busy:
return GetImageWithColorFilter(this._AvailablePicture, Colors.Red);
default:
throw new NotImplementedException();
}
}
}
您可能想看看WPF着色器效果库,其中包含一个单色效果,您可以使用一些触发器@HighCore well thanx应用该效果,但问题的目的不是应用颜色效果或图像处理…我的问题更多地与绑定相关,我有一个绑定问题。请再次检查我的问题,你会发现我在问什么,但我有一个问题。在图像处理方面,这与绑定有什么不同。我的意思是,每次可用性发生变化时,也应该以这种方式执行图像处理代码。我说的对不对@bouvierr?或者,您是否尝试为同一联系人的每个可用状态设置多个图像?如果没有,那么您的交换机是如何工作的?嗯,我对C#和WPF完全陌生,所以可能我错了,这就是为什么我无法理解InotifyProperty是如何更改的,而这段代码将如何工作的?thanx mate我想对你的解决方案投赞成票,但由于我的帐户是新的,我需要15个信誉点,所以我会按照我的想法去做;)。第一个解决方案很有趣,因为它节省了处理时间,据我所知,我们必须编写逻辑,根据每个用户的可用性创建不同的图像,应用程序加载了所有联系人,对吗?如果是,那么当用户更改其帐户图片时,它将如何为不同的可用性创建图像。我认为应该如何将其与图像的NotifyPropertyChange链接,对吗?在您的第二个解决方案中,仅用于测试,我为脱机模式编写了一些代码,以使图像变为灰色,但面临一个问题,因为图像类型为Stream,转换后,我有一个FormatConvertedBitmap,我不知道如何。。。。。将其转换回流。我将添加代码作为下一条注释*******************请参阅下一条注释*******************我想如果我将其保存在一个文件中,我们可以将数据作为流读取。我搜索了如何将FormatConvertedBitmap保存到文件,但没有找到任何函数。如果您有任何解决方案,您可以建议:)
public BitmapImage Image
{
get
{
switch (this.Availability)
{
case ContactAvailability.Available:
return this._AvailablePicture;
case ContactAvailability.Busy:
return GetImageWithColorFilter(this._AvailablePicture, Colors.Red);
default:
throw new NotImplementedException();
}
}
}