2013-04-17 68 views
0

對於我的WPF Datagrid,我使用繼承DependencyObject的IValueConverter,所以我可以添加額外的參數。問題是我的轉換器沒有被通知它的參數已經改變。轉換函數運行時,屬性是默認值。沒有綁定到IValueConverter DependencyProperty發生

下面是一些代碼。請注意,屬性名稱已被更改以保護無辜者。

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

良好的MVVM有助於緩解各地轉換器的必要性。創建一個合適的ViewModel來保存你的數據(和邏輯),並讓UI有一個綁定的值,從而刪除轉換器。 –

+0

我也會喜歡這樣的。但是,直到我們可以廢棄這個項目並從頭開始重寫它...... – raykendo

回答

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

descriped
1

自Freezable繼承,據我瞭解,它的延遲綁定,所以你可以使用對象作爲資源。

相關問題