【发布时间】:2017-07-06 03:56:29
【问题描述】:
我有一个独特的情况。在一个类中,我有一个内部类,它几乎只是一个“显示”类。在外部类中有一个名为 GetDisplayObject 的方法,它返回内部类的类型。
我正在尝试使用外部类绑定到数据网格,但通过使用转换器,我想获得正确的显示。这样我就不必在我们的应用程序中更改一堆代码,只需在几个 .xaml 文件中添加几行即可。
我制作了一个小测试应用程序,它在最基本的层面上总结了我的问题。理想情况下,我想通过使用转换器并仅将值返回作为显示来解决问题,这样当我使用 SelectedItem 时,我就不必更改大量取决于该特定类型的代码(在这种情况是 DataObject 类型)。
这是我一直在处理的对象
namespace TestApp
{
public class DataObject
{
public class DataObjectDisplay
{
public string ObjectDisplay { get; set; }
}
// props
public int Id { get; set; }
public object Object1 { get; set; }
public object Object2 { get; set; }
// method for getting the display
public DataObjectDisplay GetDisplayObject()
{
DataObjectDisplay display = new DataObjectDisplay();
// logic for determining which object should be displayed
if(Object1 == null)
{
display.ObjectDisplay = "Object1";
}
else
{
display.ObjectDisplay = "Object2";
}
return display;
}
}
}
这是我的 xaml 背后的代码
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
namespace TestApp
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
this.DataContext = this;
InitializeComponent();
this.DataObjectCollection = new ObservableCollection<DataObject>();
this.DataObjectCollection.Add(new DataObject() { Id = 1, Object1 = "this", Object2 = "that" });
this.DataObjectCollection.Add(new DataObject() { Id = 1, Object2 = "that" });
this.SelectedItem = new DataObject();
}
private ObservableCollection<DataObject> dataObjectCollection;
private DataObject selectedItem;
public ObservableCollection<DataObject> DataObjectCollection
{
get { return this.dataObjectCollection; }
set
{
dataObjectCollection = value;
OnNotifyPropertyChanged("DataObjectCollection");
}
}
public DataObject SelectedItem
{
get { return this.selectedItem; }
set
{
selectedItem = value;
OnNotifyPropertyChanged("SelectedItem");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnNotifyPropertyChanged(string property = "")
{
if(PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
}
这是 xaml(这就像我想要做的事情,使用 itemtemplate 或类似的东西,然后是调用此 GetDisplay 函数的转换器)
<Window x:Class="TestApp.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:TestApp"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:DataObjectToDisplayDataObjectConverter x:Key="ToDisplayConverter"/>
</Window.Resources>
<StackPanel>
<DataGrid ItemsSource="{Binding DataObjectCollection}" SelectedItem="{Binding SelectedItem}" MinHeight="200">
<DataGrid.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Converter={StaticResource ToDisplayConverter}}"/>
</DataTemplate>
</DataGrid.ItemTemplate>
</DataGrid>
</StackPanel>
</Window>
最后是转换器
using System;
using System.Globalization;
using System.Windows.Data;
namespace TestApp
{
public class DataObjectToDisplayDataObjectConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null && value.GetType() == typeof(DataObject))
{
DataObject dataObj = (DataObject)value;
dataObj.GetDisplayObject();
return dataObj;
}
return "Invalid Value";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
我愿意接受建议,但这是一个小例子。在我们的实际应用程序中,更改一件事很可能会引发巨大的考验。
【问题讨论】:
-
首先将
this.DataContext = this;放在InitializeComponent();之后。我希望您仅将窗口用作测试应用程序的视图模型,而不是其他任何地方。其次,你的问题是什么?您已经描述了您的应用程序的架构,但它有什么问题?不要使用value.GetType() == typeof(DataObject)。有is和as运算符。您不应为DataGrid指定ItemTemplate。如果需要自定义单元格内容,则需要指定列并为它们定义CellTemplate。 -
是的,我只是快速地把它放在一起,试图为这种情况提供一些体面的背景。澄清一下,我的问题是我不想将我的 itemsSource 更改为 DataObjectDisplay 的集合。但这就是我想要在 UI 上呈现的内容。
-
是的,您不想更改
ItemsSource。但是您已经自己为您的任务提供了解决方案:转换器。你问这样行吗?这是您的实际问题吗? -
我正在寻找一种简单的解决方案,因此我不必更改很多东西。我希望有像 itemTemplate 这样简单的东西。但是,看起来在每列单元格模板上都有一个转换器可能是最简单的解决方案
标签: c# wpf xaml datagrid ivalueconverter