带参数的 WPF MVVM 数据绑定?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21777164/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 10:51:16  来源:igfitidea点击:

WPF MVVM Databinding with parameters?

c#wpfdata-bindingmvvm

提问by Ben

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.

我显然已经去掉了大部分属性,现在 HasChanged 是纯粹的神话,但我希望以某种方式,我可以将 DataGridTextColumn 前景(或希望背景)绑定到这个 HasChanged 方法,并以某种方式通过它是哪个参数当前正在调用该方法。

<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.

我希望有一些聪明的方法可以让绑定识别哪个属性发生了变化,这与 IDataErrorInfo 允许为每个属性绑定验证的方式非常相似。虽然我不知道它在后台的实际运作方式。

回答by mcwyrm

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 DataGridTextColumns, so change your column's XAML to something like the following:

更新二:...显然我们不能改变DataGridTextColumns的背景,所以将您的列的 XAML 更改为如下所示:

<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>

回答by michal.ciurus

There are two options:

有两种选择:

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

  • If not, use the Command System. The ideal scenario would be:
    - The UI sends a Commandto the ViewModelthat something has changed.
    - The ViewModelexecutes the command, and changes the Colorfield. UI needs to be informed that the color has changed.

  • 如果这个Property东西在绑定到 ViewModel 的 UI 中,您可以监听该属性的更改,ViewModel然后相应地更改颜色。

  • 如果没有,请使用命令系统。理想的情况是:
    -用户界面发送CommandViewModel事情有了变化。
    -ViewModel执行命令,并更改Color字段。需要通知 UI 颜色已更改。

Here's an implementation of ICommand interface:

这是 ICommand 接口的实现:

http://wpftutorial.net/DelegateCommand.html

http://wpftutorial.net/DelegateCommand.html