2013-04-17 5 views
0

내 WPF Datagrid에 대해 추가 매개 변수를 추가 할 수 있도록 DependencyObject를 상속하는 IValueConverter를 사용하고 있습니다. 문제는 내 변환기가 매개 변수가 변경되었다는 알림을받지 못한다는 것입니다. convert 함수가 실행되면 속성이 기본값이됩니다.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) : 내가 그것을 이해 Freezable에서

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은 어디서나 변환기의 필요성을 덜어줍니다. 데이터 (및 로직)를 보유하고 UI에 바인드 할 단일 값이 있도록 적절한 ViewModel을 작성하여 변환기를 제거하십시오. –

+0

나는 그것도 좋아했을 것이다. 하지만이 프로젝트를 스크랩하고 처음부터 다시 작성할 때까지 ... – raykendo

답변

0

컨버터에 하나 개 이상의 매개 변수를 전달하는 가장 쉬운 방법은 사용하는 것입니다 MultiBinding

C#

XAML
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]; 
    } 
} 

:

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

그러나 가장 좋은 방법은 HighCore

으로 설명하겠다됩니다
1

상속은, 그것은 당신이 자원으로 개체를 사용할 수 있도록 바인딩을 지연 .