Reputation: 640
For my WPF Datagrid, I'm using an IValueConverter that inherits DependencyObject, so I can add extra parameters. The problem is that my converter is not being notified that its parameters have changed. When the convert function runs, the properties are the default values.
Here's some of the code. Note that Property names have been changed to protect the innocent.
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>
Code behind (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
Upvotes: 0
Views: 1691
Reputation: 119
The easiest way to pass more than one parameter to a converter is to use 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>
But the best way is descriped by HighCore
Upvotes: 0
Reputation: 12533
Inherit from Freezable , as i understand it , it delays the binding so you can use the object as a resource .
Upvotes: 1