简体   繁体   中英

WPF MVVM Databinding with parameters?

So my previous question seem to not be answerable, so i'm going to give this a go with a suggestion of my own.

The functionality im looking for, is having a datagrid change the Foreground (or even background) of a cell, when the data in that cell has been edited.

My Model looks something like this:

Public class Shipment : PropertyChangedBase
{
    #region Fields
    private ShippingService.Shipment.lbnshipment _localShipment;
    private ShippingService.Shipment.lbnshipment _originalShipment;
    #endregion

    #region Properties
    public int ShipmentID
    {
        get { return _localShipment.ShipmentID; }
        set
        {
            if(value != _localShipment.ShipmentID)
            {
                _localShipment.ShipmentID = value;
                NotifyOfPropertyChange(() => ShipmentID);
            }
         }
    } 

    public Shipment(ShippingServices.Shipment.lbnShipment localshipment)
    {
        _originalShipment = localshipment;
        _localShipment = localshipment;
    }

    //This Section is my best guess solution, but it just a guess
    public Color HasChanged(string Property)
    {
        switch(Property)
        {
           case "ShipmentID":
               if(_localShipment.ShipmentID != _originalShipment.ShipmentID)
               {
                  return Colors.Red;
               } else {
                  return Colors.Black;
               }
               break;
        }
    }
}

I've obviously stripped out most of the properties, and the HasChanged right now is pure myth, but what i'm hoping for is that somehow, i can bind a DataGridTextColumn Foreground(or background hopefully) to this HasChanged method, and somehow pass it which paramater is currently calling the method.

<DataGridTextColumn Header="ShipmentID" Binding="{Binding ShipmentID}" Foreground="{Binding HasChanged}" />

I'm hoping there is some clever way for me to allow the binding to identify which property has changed, much in the same way that IDataErrorInfo allows validation to be bound per property. Although i have no idea how that actually functions in the background.

It calls out for a converter, no? So your binding would look like this:

<DataGridTextColumn.Foreground>
    <SolidColorBrush Color="{Binding Converter={StaticResource hasChangedConverter}, ConverterParameter='ShipmentID'}"/>
</DataGridTextColumn.Foreground>

And your converter would look like (stripping extraneous code):

class HasChangedConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var shipment = value as Shipment;
        var property = parameter as string;

        return shipment.HasChanged(property);
    }
}

UPDATE: Using single quotes on the converter parameter as shown above ought to work. Failing that, you can use the extended format for the binding:

<SolidColorBrush.Color>
    <Binding Converter="{StaticResource hasChangedConverter}" ConverterParameter="ShipmentID"/>
</SolidColorBrush.Color>

UPDATE II: ... and obviously we can't go around changing the background of DataGridTextColumn s, so change your column's XAML to something like the following:

<DataGridTemplateColumn Header="ShipmentID">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding ShipmentID}">
                <TextBlock.Background> 
                    <SolidColorBrush Color="{Binding Path=ShipmentID, Converter={StaticResource HasChangedConv}}"/>
                </TextBlock.Background>
            </TextBlock>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

There are two options:

  • If this Property thing is in UI binded to the ViewModel You can listen on changes of that property in the ViewModel and then changed the color accordingly.

  • If not, use the Command System. The ideal scenario would be:
    - The UI sends a Command to the ViewModel that something has changed.
    - The ViewModel executes the command, and changes the Color field. UI needs to be informed that the color has changed.

Here's an implementation of ICommand interface:

http://wpftutorial.net/DelegateCommand.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM