0

对于我的 WPF Datagrid,我使用的是继承 DependencyObject 的 IValueConverter,因此我可以添加额外的参数。问题是我的转换器没有被通知其参数已更改。当转换函数运行时,属性是默认值。

这是一些代码。请注意,属性名称已更改以保护无辜者。

XAML:

<UserControl x:Class="UselessTool"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:my="clr-namespace:Lots.Of.Useless.Stuff"
             x:Name="Myself">
  <Grid x:Name="LayoutRoot">
    <Grid.Resources>
      <my:InvasiveWeightConverter x:Key="TotalWeightConverter"
                                  Department="{Binding Department, ElementName=Myself}" />
    </Grid.Resources>
    <DataGrid x:Name="BuildingGrid"
              ItemsSource="{Binding BuildingData, ElementName=Myself}">
      <DataGrid.Columns>
        <DataGridTextColumn Header="Building"
                            Binding="{Binding Building}" />
        <DataGridTextColumn Header="Room"
                            Binding="{Binding Room}" />
        <DataGridTextColumn Header="Fire Escapes"
                            Binding="{Binding FireEscapes}" />
        <DataGridTextColumn Header="Total Personnel Weight"
                            Binding="{Binding Room, Converter={StaticResource TotalWeightConverter}, Mode=TwoWay}" />
      </DataGrid.Columns>
    </DataGrid>
  </Grid>
</UserControl>

背后的代码(VB.NET):

Imports System.Data
Imports System.ComponentModel
Public Class UselessTool
  Implements INotifyPropertyChanged

  Public Sub New()
    Me.Department = ""
    Me.BuildingData = New DataTable
  End Sub

  Public Sub ImportTables(BuildingTable as DataTable, department as String)
     Me.Department = department
     Me.BuildingData = BuildingTable.Select("[Department] = " & department).CopyToDataTable()
  End Sub

  Private _dept as String
  Public Property Department() as String
    Get
      return _dept
    End Get
    Set(value as String)
      _dept = value
      RaisePropertyChanged("Department")
    End Set
  End Property
  ....
End Class

Public Class InvasiveWeightConverter
  Inherits DependencyObject
  Implements IValueConverter

  Public Shared ReadOnly DepartmentProperty As DependencyProperty = DependencyProperty.Register("Department", GetType(String), GetType(InvasiveWeightConverter), New PropertyMetadata(Nothing, New PropertyChangedCallback(AddressOf DPChangeHandler)))

  Public Property Department() As String
      Get
          Return DirectCast(GetValue(DepartmentProperty), String)
      End Get
      Set(value As String)
          SetValue(DepartmentProperty, value)
      End Set
  End Property

  Private Shared Sub DPChangeHandler(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
    MsgBox(e.NewValue.ToString)
    ' the part above is not being fired
  End Sub

  Public Function Convert(value As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
    Dim room As String = CType(value, String)

    Dim dataTable As DataTable = Personnel_Table
    Dim clause As String = String.Format("[{0}] = '{1}' AND [{2}] = '{3}'", dataTable.DepartmentColumn.ToString, Department, dataTable.RoomColumn.ToString, room)
    ' this is where I notice that Department is empty
    Dim rows() As DataRow = dataTable.Select(clause, "", DataViewRowState.CurrentRows)

    Dim totalWeight As Integer
    Dim weight As Integer
    For Each row In rows
        weight = CInt(row.Item("Weight"))
        totalWeight += weight 
    Next
    Return totalWeight 

  End Function

  Public Function ConvertBack(value As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
    Return Nothing
  End Function

End Class
4

2 回答 2

1

从 Freezable 继承,据我了解,它会延迟绑定,因此您可以将对象用作资源。

于 2013-04-17T23:40:45.700 回答
0

将多个参数传递给转换器的最简单方法是使用 MultiBinding

C#

public class TotalWeightConverter : IMultiValueConverter
{
    public override object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        ResultType result;
        var room =(RoomType)value[0];
        var department = (DepartmentType)value[1];

        // Do something
        return result;
    }

    public override object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        // Do somethig
        return new object[2];
    }
}

XAML:

<DataGridTextColumn Header="Total Personnel Weight">
    <DataGridTextColumn.Binding>
        <MultiBinding Converter={StaticResource TotalWeightConverter}>
            <Binding Path="Room" />
            <Binding Path="Department" Mode="OneWay"/>
        </MultiBinding>
    </DataGridTextColumn>
</DataGridTextColumn>

但是最好的方法是由 HighCore 描述的

于 2013-04-19T10:46:49.690 回答