2011-08-14 4 views
1

나는 거의 일주일 동안이 문제에 대한 해답을 찾고 있었고 나는 이것을 할 방법을 찾지 못하고있다. 나는 비교적 단순한 것 같아요 ...ListView 내에서 TextBox에 바인딩 하시겠습니까?

저는 ListView가 있고 GridViewColumn에는 TextBox 항목이 들어 있습니다. ListView 바로 아래에 Label을 놓고 모든 TextBox에있는 항목의 합계로 채 웁니다. 누군가가 TextBox에서 값을 변경하면 합계도 변경되어야합니다.

어떤 도움도 대단히 감사하겠습니다 ...

은 내가 합계를 얻기 위해 컨버터를 사용할 필요가 알아 ...하지만 난 바인딩 권리를 얻는 방법을 모르겠어요!

편집 : 약간 다른 방식으로 해결했습니다. 아래에 내 솔루션을 게시 할 것입니다.

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:converters="clr-namespace:WpfApplication2" 
    Title="MainWindow" Height="350" Width="525"> 

    <Window.Resources> 
     <XmlDataProvider x:Key="myParties" XPath="Parties" Source="XMLFile1.xml" /> 
     <CollectionViewSource x:Key="myCollectionViewSource" Source="{StaticResource myParties}" /> 
     <converters:SumConverter x:Key="mySumConverter" /> 
    </Window.Resources> 

    <StackPanel> 
     <Button x:Name="Breakpoint" Click="bpClick" Content="Breakpoint"/> 
     <ListView x:Name="myListView" 
        HorizontalAlignment="Stretch" 
        ItemsSource="{Binding Source={StaticResource myCollectionViewSource},XPath='Party',Mode=TwoWay}"> 
      <ListView.View> 
       <GridView> 
        <GridViewColumn Width="100" DisplayMemberBinding="{Binding XPath='@Contact'}" Header="Contact"/> 
        <GridViewColumn DisplayMemberBinding="{Binding XPath='@Qty'}" Header="Q"/> 
        <GridViewColumn DisplayMemberBinding="{Binding XPath='@Amount'}" Header="Amt"/> 
        <GridViewColumn x:Name="tbTot" Header="Tot"> 
         <GridViewColumn.CellTemplate> 
          <DataTemplate> 
           <DockPanel> 
            <TextBox Width="100" Text="{Binding XPath='@Tot'}" /> 
           </DockPanel> 
          </DataTemplate> 
         </GridViewColumn.CellTemplate> 
        </GridViewColumn> 
       </GridView> 
      </ListView.View>  
     </ListView> 

     <Label Height="22"> 
      <Label.Content> 
       <MultiBinding Converter="{StaticResource mySumConverter}"> 
        <Binding ElementName="myListView" Path="Items"/> 
        <Binding ElementName="myListView" Path="Items.Count"/> 
       </MultiBinding> 
      </Label.Content> 
     </Label> 
    </StackPanel> 
</Window> 

XML 파일 :

<?xml version="1.0" encoding="utf-8" ?> 
<Parties> 
    <Party Contact="Jim Shmekel" 
     Qty="1" 
     Amount="55.00" 
     Tot="55.00"/> 
    <Party Contact="Shmi Skywalker" 
     Qty="1" 
     Amount="20.00" 
     Tot="20.00"/> 
    <Party Contact="Jon Ronson" 
     Qty="1" 
     Amount="23.00" 
     Tot="23.00"/> 
</Parties> 

SumConverter :

Imports System.Collections.ObjectModel 
Imports System.Reflection 

<ValueConversion(GetType(Object()), GetType(String))> 
Public Class SumConverter : Implements System.Windows.Data.IMultiValueConverter 

    Public Function Convert(ByVal values() As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IMultiValueConverter.Convert 
     Static lvItems As IList 
     Static lvItem As Xml.XmlElement 
     Dim nVal As Double 

     Convert = 0 
     lvItems = values(0) 
     If lvItems Is Nothing Then Exit Function 

     For Each lvItem In lvItems 
      'Debug.Print(lvItem.GetAttribute("Tot")) 
      If Double.TryParse(lvItem.GetAttribute("Tot"), nVal) Then 
       Convert = Convert + nVal 
      End If 
     Next 

    End Function 

    Public Function ConvertBack(ByVal value As Object, ByVal targetTypes() As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object() Implements System.Windows.Data.IMultiValueConverter.ConvertBack 
     ConvertBack = Nothing 
    End Function 
End Class 

답변

1

솔직한 솔루션 (I 확신하지 최적)을

ElementName = myListView, Path = Items 

을 결합하는 것입니다 그리고 변환기에서 항목을 통과 함 d VisualTreeHelper.GetChild()을 사용하여 항목의 기본 TextBlock을 확인한 다음 int.TryParse(textBlock.Text, out currentItemValue);

+0

안녕 sllev-- 주셔서 감사합니다 빠른 응답을 너무 많이. 나는 이것이 내가 있어야 할 곳에 가까이 다가 갈 수 있다고 생각하지만, 지금 실행하면 프로그램이 시작될 때 (Items.Count = 0) 한 번만 내 변환기를 호출하고, 다시는 호출하지 않는다. 어떤 아이디어? (위의 내 SumConverter 코드 추가). – transistor1

+0

@ transistor1 : [this] (http://stackoverflow.com/questions/7003074/how-can-i-add-a-value-when-i-use-groupping-by-in-datagrid/7003686#7003686)를 참조하십시오.). (Keypoint 존재 : items.count 속성을 대상으로하는 하나의 바인딩으로 멀티 바인딩하여 업데이트 됨) –

+0

그래서 항목을 추가 할 때 다시 호출되지 않습니까? – sll

0

슬레브가 제안한 방식에 실제로 접근하려고하기 때문에 조금 실망했습니다. 나에게, 그것은 그것을하는 가장 논리적 인 방법처럼 보였다. 여전히 방법이 있을지 모르지만 나는 그것을 알아 내지 못했습니다.

다음은이 문제를 해결하는 방법입니다. 기본적으로 내 DataSource에 "Tot"열을 추가했습니다. (위의 질문에 있지만 초기 솔루션에는 없었습니다.) TextBox를 해당 열에 바인딩 한 다음 ListView 내 TextBox의 LostFocus 이벤트에서 ListView를 새로 고칩니다. Refresh()를 호출하면 SumConverter가 다시 호출됩니다.

희망에 따라 이것은 다른 사람을 도우려는 것입니다. 간단한 요청처럼 보였지만 시간이 많이 걸렸습니다.

MainWindow.xaml : MainWindow.xaml에

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:converters="clr-namespace:WpfApplication2" 
    Title="MainWindow" Height="350" Width="525"> 

    <Window.Resources> 
     <XmlDataProvider x:Key="myParties" XPath="Parties" Source="XMLFile1.xml" /> 
     <CollectionViewSource x:Key="myCollectionViewSource" Source="{StaticResource myParties}" /> 
     <converters:SumConverter x:Key="mySumConverter" /> 
    </Window.Resources> 

    <StackPanel> 
     <ListView x:Name="myListView" 
        HorizontalAlignment="Stretch" 
        ItemsSource="{Binding Source={StaticResource myCollectionViewSource},XPath='Party',Mode=TwoWay}"> 

      <ListView.View> 
       <GridView> 
        <GridViewColumn Width="100" DisplayMemberBinding="{Binding XPath='@Contact'}" Header="Contact"/> 
        <GridViewColumn DisplayMemberBinding="{Binding XPath='@Qty'}" Header="Q"/> 
        <GridViewColumn DisplayMemberBinding="{Binding XPath='@Amount'}" Header="Amt"/> 
        <GridViewColumn x:Name="tbTot" Header="Tot"> 
         <GridViewColumn.CellTemplate> 
          <DataTemplate> 
           <DockPanel> 
            <TextBox LostFocus="TextBox_LostFocus" Width="100" Text="{Binding XPath='@Tot'}" /> 
           </DockPanel> 
          </DataTemplate> 
         </GridViewColumn.CellTemplate> 
        </GridViewColumn> 
       </GridView> 
      </ListView.View>  
     </ListView> 

     <Label VerticalAlignment="Stretch"> 
      <Label.Content> 
       <MultiBinding Converter="{StaticResource mySumConverter}"> 
        <Binding ElementName="myListView" Path="Items"/> 
        <Binding ElementName="myListView" Path="Items.Count"/> 
       </MultiBinding> 
      </Label.Content> 
     </Label> 
    </StackPanel> 
</Window> 

코드 숨김 :

Class MainWindow 

     Public Sub New() 
      ' This call is required by the designer. 
      InitializeComponent() 
     End Sub 

     Private Sub TextBox_LostFocus(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) 
      myListView.Items.Refresh() 
     End Sub 
    End Class 

SumConverter.vb :

<ValueConversion(GetType(Object()), GetType(String))> 
Public Class SumConverter : Implements System.Windows.Data.IMultiValueConverter 

    Public Function Convert(ByVal values() As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IMultiValueConverter.Convert 
     Static lvItems As ItemCollection 
     Static lvItem As Xml.XmlElement 
     Dim nVal As Double 

     Convert = 0 
     lvItems = values(0) 
     If lvItems Is Nothing Then Exit Function 


     For Each lvItem In lvItems 
      'Debug.Print(lvItem.GetAttribute("Tot")) 
      If Double.TryParse(lvItem.GetAttribute("Tot"), nVal) Then 
       Convert = Convert + nVal 
      End If 
     Next 

    End Function 

    Public Function ConvertBack(ByVal value As Object, ByVal targetTypes() As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object() Implements System.Windows.Data.IMultiValueConverter.ConvertBack 
     ConvertBack = Nothing 
    End Function 
End Class 
관련 문제