我对WPF很新,我正在尝试使用dataGrid
。我试图显示的一些数据是图像。首先,我试着像这样绑定数据:
DataGrid.ItemsSource = <some collection>
这导致一个列包含Image的路径,而不是显示图像。
我开始谷歌搜索,我想出了以下内容:
我创建了一个数据模板:
<DataTemplate x:Key="ImageDataTemplate">
<Image Source="{Binding Image}"/>
</DataTemplate>
我在AutoGeneratingColumn
事件中添加了一个函数,并在那里放了以下代码:
if (typeof(System.Windows.Media.ImageSource).IsAssignableFrom(e.PropertyType))
{
DataGridTemplateColumn dgtc = new DataGridTemplateColumn();
dgtc.Header = e.Column.Header;
dgtc.CellTemplate = this.FindResource("ImageDataTemplate") as DataTemplate;
e.Column = dgtc;
}
女巫工作正常,只要我调用我的班级Image
中的所有图像属性,有没有办法更灵活一点? (我想要一个类中的一些图像,或者具有图像属性的含义全名,我不喜欢几乎重复的代码)
答案 0 :(得分:0)
也许你可以使用DataTemplateSelector?
看一下这篇文章:http://tech.pro/tutorial/807/wpf-tutorial-how-to-use-a-datatemplateselector
答案 1 :(得分:0)
这是一个非常具有误导性的标题,你看到“未知”这个词在你的问题中没有出现。无论哪种方式,DataGrid
都是一个有点复杂的控件,你似乎是从WinForms的角度来看,通过使用C#代码操作它,而不是简单地定义你希望它在XAML中的外观,在WPF中是惯例。
我强烈建议您在继续之前阅读一些有关如何以WPF方式使用它的教程... 许多这样的教程,但是WPF DataGrid Control一个在WPF Tutorials.NET上是一个很好的开始。
简而言之,您可以从链接的教程中定义XAML中每列的内容......
<DataGrid ItemsSource="{Binding Customers}" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTemplateColumn Header="Image" Width="SizeToCells" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Image}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
答案 2 :(得分:0)
我个人会将datagrid的AutoGenerateColumns
属性设置为false
,并在XAML中手动创建列。
AutoGenerateColumns
不是那么有用的IMO。您经常在模型中拥有不会在列中显示的属性,如果它由AutoGeneratingColumn
事件的处理程序结束,则您将失去不为列显示编写代码的好处。
答案 3 :(得分:0)
您可以将数据网格绑定到可观察的集合,并像这样构建集合......
public class ViewModel : INotifyPropertyChanged
{
public ObservableCollection<ImageContainer> MyImageCollection { get; set; }
public ViewModel()
{
MyImageCollection = new ObservableCollection<ImageContainer>();
MyImageCollection.Add(new ImageContainer{Source = xxx});
}
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string name)
{
var handler = System.Threading.Interlocked.CompareExchange(ref PropertyChanged, null, null);
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
#endregion
}
public class ImageContainer : INotifyPropertyChanged
{
private BitmapImage _source;
public BitmapImage Source
{
[DebuggerStepThrough]
get { return _source; }
[DebuggerStepThrough]
set
{
if (value != _source)
{
_source = value;
OnPropertyChanged("Source");
}
}
}
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string name)
{
var handler = System.Threading.Interlocked.CompareExchange(ref PropertyChanged, null, null);
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
#endregion
}
这段代码定义了一个可观察的图像集合以及每个图像的绑定容器。如图所示,View Model构造函数生成集合的一个实例,并开始用图像填充它。容器类没有 HAVE 来实现INPC,但我不知道你对图像做了什么,所以无论如何都包含了INPC(INotifyPropertyChanged)。
相应的Xaml看起来像这样......
<DataGrid ItemsSource="{Binding MyImageCollection}" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Source}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
如果从磁盘读取图像,一种流行的变体是绑定到FileInfo类并使用转换器返回图像。这种方法使视图模型不那么混乱,但任何一种设计都会给出你想要的东西。
事后补充:如果您仅将数据网格用于显示图像集,请考虑使用项目控件。这样做可以避免数据网格的开销。