[英]WPF DataGrid, customizing the display with a converter
我有一個獨特的情況。 在一個類中,我有一個內部類,它幾乎只充當“顯示”類。 在外部類中,有一個名為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();
}
}
}
我願意接受建議,但這只是一個小例子。 在我們實際的應用程序中,更改一件事情很可能會帶來巨大的考驗。
如果我是我,我將更改視圖與ViewModel的緊密耦合,就像創建新的MainWindowViewModel類並在其中包含所有屬性一樣。
我看到的另一件事是GetDisplayObject方法,需要從轉換器調用這樣的方法。
您可以重構此代碼,並在轉換器中放入類似的內容。
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
DataObject dataObj = value as DataObject;
if (value == null)
{
return "Invalid Value";
}
if (dataObj.Object1 == null)
{
return "Object1";
}
return "Object2";
}
幸運的是,因為這是一個對象是否為空並且相關字符串為空的問題,所以我能夠將優先級綁定與轉換器一起使用,以返回DependencyProperty.UnsetValue並強制其使用下一個綁定。 我認為這是針對這種情況的最佳解決方案。
因此,xaml最終看起來像這樣。
<DataGrid ItemsSource="{Binding DataObjectCollection}" SelectedItem="{Binding SelectedItem}" MinHeight="200">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<PriorityBinding>
<Binding Path="Object1" Converter="{StaticResource EmptyStringToDependencyPropertyUnset}"/>
<Binding Path="Object2"/>
</PriorityBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
轉換器最終像這樣
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value == null || value as string == string.Empty)
{
return DependencyProperty.UnsetValue;
}
return value;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.