2014-09-13 95 views
1

我正在使用WPF聊天控制變量和我設計ListView房間列表WPF得到的ListView

MainWindow.xaml

<ListView x:Name="listView_RoomList" Grid.Row="1" Grid.ColumnSpan="2" 
      ScrollViewer.HorizontalScrollBarVisibility="Visible" SelectionMode="Single" 
      Visibility="{Binding ElementName=comboBox_CntList, Path=Items.IsEmpty, 
             Converter={StaticResource VisibilityConverter}}"> 
    <ListView.View> 
     <GridView ColumnHeaderTemplate="{Binding Path=Rooms}"> 
      <GridView.Columns> 
       <GridViewColumn x:Name="gridViewColumn_RoomName" Width="100"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <Label Content="{Binding Path=Name}"/> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn x:Name="gridViewColumn_Master" Width="100"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <Label Content="{Binding Path=Master}"/> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn x:Name="gridViewColumn_MaxConnectorNum"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <Label Content="{Binding Path=MaxConnectorNum, Converter={StaticResource MaxConnectorNumConverter}}"/> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn x:Name="gridViewColumn_IsNeedPassword"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <PasswordBox x:Name="passwordBox_PW" MinWidth="100" IsEnabled="{Binding Path=IsNeedPassword}"/> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn x:Name="gridViewColumn_EntryButton"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <Button Background="Aqua" Click="button_Entry_Click"> 
           <StackPanel Orientation="Horizontal"> 
            <Image Height="Auto" Width="Auto" Source="Resources/login.png"/> 
            <TextBlock Text="{Binding Converter={StaticResource EntryButtonConverter}}" VerticalAlignment="Center"/> 
           </StackPanel> 
           <Button.Tag> 
            <!-- I can get a Room ID!! --> 
            <Binding Path="ID"/> 
           </Button.Tag> 
          </Button> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn x:Name="gridViewColumn_DeleteButton"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <Button Background="Orange" Click="button_Delete_Click" IsEnabled="{Binding Path=Master, Converter={StaticResource DeleteButtonVisibilityConverter}}"> 
           <StackPanel Orientation="Horizontal"> 
            <Image Height="Auto" Width="Auto" Source="Resources/login.png"/> 
            <TextBlock Text="{Binding Converter={StaticResource DeleteButtonConverter}}" VerticalAlignment="Center"/> 
           </StackPanel> 
          </Button> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
      </GridView.Columns> 
     </GridView> 
    </ListView.View> 
</ListView> 

一個GridView RowRoom類。

Room.cs

public class Room 
{ 
     public uint ID { get; private set; } 

     public string Name { get; private set; } 

     public string Master { get; internal set; } 

     public short MaxConnectorNum { get; private set; } 

     public bool IsNeedPassword { get; private set; } 
} 

每個房間都有一個ID

因此,當叫button_Entry_Click功能,我可以得到一個房間ID。

MainWindow.xaml.cs

private void button_Entry_Click(object sender, RoutedEventArgs e) 
     { 
      Button b = (Button)sender; 

      MessageBox.Show(b.Tag); 
     } 

這樣的事情。

我能得到的只是Button 但是,我想PasswordBox輸入密碼等..

因爲我想找到方法,這是從房間ID獲得所有的行控制。

我該如何編碼?

在此先感謝。

回答

1

您需要從ListView中獲取容器並遍歷它的VisualTree,以搜索PasswordBox 控件。

首先這裏有一些你可以使用的擴展,我隨時都會保持方便。

public static class VisualTreeHelperExtensions 
{ 
    public static T FindVisualParent<T>(DependencyObject depObj) where T : DependencyObject 
    { 
     var parent = VisualTreeHelper.GetParent(depObj); 

     if (parent == null || parent is T) 
      return (T)parent; 

     return FindVisualParent<T>(parent); 
    } 

    public static T FindVisualChild<T>(DependencyObject depObj) where T : Visual 
    { 
     if (depObj != null) 
     { 
      for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
      { 
       DependencyObject child = VisualTreeHelper.GetChild(depObj, i); 

       if (child != null && child is T) 
       { 
        return (T)child; 
       } 

       foreach (T childOfChild in FindVisualChildren<T>(child)) 
       { 
        return childOfChild; 
       } 
      } 
     } 
     return null; 
    } 

    public static T FindVisualChild<T>(DependencyObject depObj, string name) where T : FrameworkElement 
    { 
     if (depObj != null) 
     { 
      for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
      { 
       DependencyObject child = VisualTreeHelper.GetChild(depObj, i); 

       if (child != null && child is T && (child as T).Name.Equals(name)) 
       { 
        return (T)child; 
       } 

       foreach (T childOfChild in FindVisualChildren<T>(child)) 
       { 
        if (childOfChild.Name.Equals(name)) 
         return childOfChild; 
       } 
      } 
     } 
     return null; 
    } 

    public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject 
    { 
     if (depObj == null) 
      yield break; 

     for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
     { 
      DependencyObject child = VisualTreeHelper.GetChild(depObj, i); 

      if (child != null && child is T) 
      { 
       yield return (T)child; 
      } 

      foreach (T childOfChild in FindVisualChildren<T>(child)) 
      { 
       yield return childOfChild; 
      } 
     } 
    }    
} 

現在,這裏是你如何能得到你的ListView的第一個房間的PasswordBox一個例子:

CS:

public List<Room> Rooms 
    { 
     get 
     { 
      return new List<Room> 
      { 
       new Room{ Name = "A"} , 
       new Room{ Name = "B"} 
      }; 
     } 
    } 

    private void Button_Click_1(object sender, RoutedEventArgs e) 
    { 
     var rooms = listView_RoomList.Items.Cast<Room>().ToList(); 

     var generator = listView_RoomList.ItemContainerGenerator; 

     ListViewItem container = (ListViewItem)generator.ContainerFromItem(rooms[0]); 

     PasswordBox pwd = (PasswordBox)VisualTreeHelperExtensions.FindVisualChild<PasswordBox>(container); 
     string password = pwd.Password; 
    } 

XAML:

<Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition /> 
     </Grid.RowDefinitions> 

     <Button Content="Submit" Click="Button_Click_1" /> 

     <ListView x:Name="listView_RoomList" Grid.Row="1" ItemsSource="{Binding Rooms}" 
       ScrollViewer.HorizontalScrollBarVisibility="Visible" SelectionMode="Single"> 
      <ListView.View> 
        <GridView> 
         <GridView.Columns> 

         <GridViewColumn> 
          <GridViewColumn.CellTemplate> 
           <DataTemplate> 
            <TextBlock Text="{Binding Name}"/> 
           </DataTemplate> 
          </GridViewColumn.CellTemplate> 
          </GridViewColumn> 

          <GridViewColumn> 
           <GridViewColumn.CellTemplate> 
            <DataTemplate> 
             <PasswordBox /> 
            </DataTemplate> 
           </GridViewColumn.CellTemplate> 
          </GridViewColumn>      
        </GridView.Columns> 
       </GridView> 
      </ListView.View> 
     </ListView>     
    </Grid> 

另外,您也可以這樣做:

XAML:

 <GridViewColumn> 
      <GridViewColumn.CellTemplate> 
       <DataTemplate>         
        <PasswordBox PasswordChanged="passwordBox_PW_PasswordChanged_1" /> 
       </DataTemplate> 
      </GridViewColumn.CellTemplate> 
    </GridViewColumn> 

CS:

private void passwordBox_PW_PasswordChanged_1(object sender, RoutedEventArgs e) 
    { 
     PasswordBox pwdBox = (PasswordBox)sender; 
     Room r = pwdBox.DataContext as Room; 
     r.Password = pwdBox.Password; 
    }  
+1

哇..你是WPF的專家?非常感謝! – Lee 2014-09-13 18:59:36