我正在使用WPF
进行聊天,我为{strong>会议室列表设计了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 Row
有Room
个类。
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获取所有行控制的方法。
我如何编码?
提前致谢。
答案 0 :(得分: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;
}