1

该应用程序是一个信使,我为此目的使用 microsoft lync 客户端。在其中一个上下文中,我在列表视图中获取联系人(这是 LyncClient 的一个对象,具有名称、图像、可用性等属性)并将它们加载到定义如下的数据模板中:

<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>

它有一个 Grid 容器,其中我们有一个图像和文本块控件,它们显示联系人的图像和名称,如下所示,stackpanel 的背景绑定到 lync联系人对象的可用性属性,并使用转换器将可用性状态映射到颜色,例如当联系人忙时,stackpanel 的背景将变为红色。

我也想对图像控件产生类似的效果。

我是绑定新手,所以完全迷失在这个绑定概念中。

我的想法是:图像有一个效果事件处理程序,所以我想为此目的使用它并使用

在某些情况下在转换器内部我想使用一些我需要获取图像源的代码,但是当我们通过绑定获取图像源时

请建议我你的想法。


正如您在代码中看到的那样, <Image Source="{Binding Image}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title} effect="{Binding Availability, Converter={StaticResource AvailabilityToPresenceColor}}"/> 我只是将图像控件的源与 Contact对象的属性绑定。我想将 Contact 对象的可用性属性发送到 IValueConverter 的 Convert 方法,或者如果可能的话,我想将图像与整个Contact对象绑定……或者如果有其他方式,请告诉我。

#####################评论附件
var bitmap = new BitmapImage();
    bitmap.BeginInit();
    MemoreyStream ms=new MemoryStream(_image);
    bitmap.StreamSource = stream;
    bitmap.CacheOption = BitmapCacheOption.OnLoad;
    bitmap.EndInit();
 var grayBitmapSource = new FormatConvertedBitmap();
    grayBitmapSource.BeginInit();
    grayBitmapSource.Source = ms;
    grayBitmapSource.DestinationFormat = PixelFormats.Gray32Float;
    grayBitmapSource.EndInit();
.....

现在问题是我有 grayBitmapSource,它的类型是 FormatConvertedBitmap,我不知道如何再次将其转换为 Stream。

4

1 回答 1

0

我建议看看这篇关于 WPF 中图像处理的文章:http: //www.codeproject.com/Articles/237226/Image-Processing-is-done-using-WPF

使用图像处理逻辑,您可以为每个可用性状态创建不同的图片。您可以使用 IValueConverter,但这意味着您必须在每次可用性状态更改时重新处理图像。相反,您可以简单地更改您的 Contact 类,以便在您更改 Availability 属性时,它会自动向 WPF 发出信号以获取 Image 属性引用的图片:

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.SourceDepencyProperty. 当一个类实现INotifyPropertyChanged时,您可以告诉 WPF 它的某个属性已更改。NotifyPropertyChanged您只需使用更改的属性名称引发事件。这会通知 WPF 更新所有DepencyProperty绑定到给定属性的 s。

就图像处理而言,这与绑定有何不同。我的意思是每次可用性发生变化时,图像处理代码也应该以这种方式执行。我是对还是错@bouvierr?

不。在这种情况下,我们将只执行固定次数的图像处理来为每个可用性状态创建图片(在我的示例中,每个联系人两次)。例如,我们可以在应用程序启动期间创建所有图片(3 个联系人 x 2 状态 = 6 个图片)并将它们存储在每个联系人的_AvailablePicture_BusyPicture字段中。

这是重要的部分:当我们设置Availability属性时,我们也调用NotifyPropertyChanged("Image"). 这将强制 WPF 更新 ,Image.Source DepencyProperty因为它绑定到Contact.Image. 这将返回一个不同的图片,因为Availability已经改变了。

在我的示例中,我决定存储图片。这可能不是您的最佳解决方案。它消耗更多内存,但节省了处理时间。如果您希望在每次可用性状态更改时重新处理图像,您应该将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();
            }
        }
    }
于 2013-01-20T16:31:28.523 回答