How to I manipulate cell data being displayed in W

2019-08-16 04:24发布

问题:

The following WPF code displays the contents of FirstName and ZipCode in the WPF Toolkit DataGrid.

However, I don't want to just display the data as it is but slightly modified, e.g. I might want to display all the zipcodes to display with a "-0000" on the end, or I may want to display "n/a" if a cell is blank.

I could only find CopyingCellClipboardContent which doesn't seem to do what I want.

I'm thinking I might need a Converter but am not sure how to go about it in this example.

How can I manipulate the cell content of the DataGrid cells at runtime?

XAML:

<Window x:Class="TestControl3423.Window2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:tk="http://schemas.microsoft.com/wpf/2008/toolkit"
    Title="Window2" Height="300" Width="500">
    <StackPanel>
        <tk:DataGrid x:Name="dataGrid" 
                     Margin="0 0 0 10"
                     AutoGenerateColumns="False" 
                     CanUserAddRows="False"
                     HeadersVisibility="Column" 
                     MaxHeight="400"
                     IsReadOnly="True"
                     Background="#fff"
                     ColumnWidth="SizeToHeader">
        </tk:DataGrid>
    </StackPanel>
</Window>

Code Behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using System.Windows.Documents;
using Microsoft.Windows.Controls;

namespace TestControl3423
{
    public partial class Window2 : Window
    {
        public Window2()
        {
            InitializeComponent();

            dataGrid.ItemsSource = Customer.GetCustomers();

            dataGrid.Columns.Clear();

            DataGridTextColumn dgtc1 = new DataGridTextColumn();
            dgtc1.Header = "First Name";
            dgtc1.Binding = new Binding("FirstName");
            dgtc1.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
            dataGrid.Columns.Add(dgtc1);

            DataGridTextColumn dgtc2 = new DataGridTextColumn();
            dgtc2.Header = "Zip Code";
            dgtc2.Binding = new Binding("ZipCode");
            dgtc2.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
            dgtc2.CopyingCellClipboardContent += new EventHandler<DataGridCellClipboardEventArgs>(dgtc2_CopyingCellClipboardContent);
            dataGrid.Columns.Add(dgtc2);
        }

        void dgtc2_CopyingCellClipboardContent(object sender, DataGridCellClipboardEventArgs e)
        {
            DataGridTextColumn dgtc = sender as DataGridTextColumn;
            dgtc.SetValue(dgtc.GetValue() + "-0000"); //ERROR
        }
    }

    public class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Street { get; set; }
        public string Location { get; set; }
        public string ZipCode { get; set; }

        public static List<Customer> GetCustomers()
        {
            List<Customer> customers = new List<Customer>();
            customers.Add(new Customer { FirstName = "Jim", LastName = "Jones", ZipCode = "23434" });
            customers.Add(new Customer { FirstName = "Joe", LastName = "Adams", ZipCode = "12312" });
            customers.Add(new Customer { FirstName = "Jake", LastName = "Johnson", ZipCode = "23111" });
            customers.Add(new Customer { FirstName = "Angie", LastName = "Reckar", ZipCode = "54343" });
            customers.Add(new Customer { FirstName = "Jean", LastName = "Anderson", ZipCode = "16623" });
            return customers;
        }

    }
}

回答1:

Pls, see if code below would work fine for you. I've made an DataGridTextColumn descendant class with overriden GenerateElement method. There you could manipulate with the TextBlock control created for the given cell, e.g alter its value to add extra digits for zip codes.

...
DataGridTextColumn dgtc2 = new ExtendedDataGridTextColumn(); 
dgtc2.Header = "Zip Code"; 
...

public class ExtendedDataGridTextColumn : DataGridTextColumn 
{
    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
    {
        TextBlock element = (TextBlock)base.GenerateElement(cell, dataItem);
        element.Text = ((Customer)dataItem).ZipCode + "-0000";
        return element;
    }
}

hope this helps, regards