WPF将控件绑定到未知属性

时间:2013-10-11 09:26:49

标签: c# wpf

我对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中的所有图像属性,有没有办法更灵活一点? (我想要一个类中的一些图像,或者具有图像属性的含义全名,我不喜欢几乎重复的代码)

4 个答案:

答案 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类并使用转换器返回图像。这种方法使视图模型不那么混乱,但任何一种设计都会给出你想要的东西。

事后补充:如果您仅将数据网格用于显示图像集,请考虑使用项目控件。这样做可以避免数据网格的开销。