簡體   English   中英

WPF DataGrid,使用轉換器自定義顯示

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM