我正在编写一个WPF客户端,并创建了一个将在客户端中使用的自定义聊天控件,聊天控件包含一个ChatClient,用于处理加入和离开聊天服务,并按以下方式显示已连接用户的列表XAML:
isGreater
这在Chat程序集的ResourceDictionary中定义,ChatClient作为控件添加到主应用程序窗口。
这一切都很棒,当我运行应用程序时,它连接到聊天服务器,我在主窗口右侧显示一个很好的面板,其中包含已连接用户的列表。
好的,所以我的问题与上面的XAML中的以下部分有关:
<Style TargetType="{x:Type chat:ChatClient}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type chat:ChatClient}">
<Grid Margin="0,0,0,0" Background="{StaticResource ChatClientBackgroundBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="135" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="0,0,0,0" Background="{StaticResource ChatClientBackgroundBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="32" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Grid.Row="0" Height="100" Margin="0,0,0,0" Padding="1,1,1,0" BorderBrush="{StaticResource ChatClientAvatarBorderBrush}">
<Image Height="80" Width="80" Source="Cleo.Windows.Ui.Chat;component/Resources/noavatar.png" StretchDirection="Both" Stretch="Fill">
<Image.Clip>
<EllipseGeometry Center="40,40" RadiusX="40" RadiusY="40" />
</Image.Clip>
</Image>
</Border>
<StackPanel Grid.Column="0" Grid.Row="1" Orientation="Horizontal">
<Ellipse Height="8" Width="8" Fill="{StaticResource ChatClientPresenceOnlineBrush}" Margin="6,-8,0,0" />
<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=CurrentPerson.Name}" Margin="8,0" Foreground="{StaticResource ChatClientTextBrush}"
FontSize="16" />
</StackPanel>
</Grid>
<Border Grid.Row="1" BorderThickness="0,1,0,0" BorderBrush="{StaticResource ChatClientBorderBrush}">
<Grid Background="{StaticResource ChatClientBackgroundBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*" MinHeight="100" />
</Grid.RowDefinitions>
<ScrollViewer x:Name="srcContacts" Grid.Row="0" Margin="0,0,0,0" VerticalScrollBarVisibility="Auto">
<StackPanel>
<ItemsControl ItemsSource="{Binding Path=People, RelativeSource={RelativeSource AncestorType={x:Type chat:ChatClient}}}" x:Name="Contacts">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl>
<Border Style="{StaticResource IsMouseOver}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Top" Height="35" Width="35" Margin="5,0,0,0"
BorderBrush="{StaticResource ChatClientPresenceOnlineBrush}" BorderThickness="2" CornerRadius="15">
<Image Height="30" Width="30" Source="Cleo.Windows.Ui.Chat;component/Resources/noavatar.png" StretchDirection="Both" Stretch="Fill">
<Image.Clip>
<EllipseGeometry Center="15,15" RadiusX="15" RadiusY="15" />
</Image.Clip>
</Image>
</Border>
<TextBlock Grid.Column="1" Grid.Row="0" Foreground="{StaticResource ChatClientTextBrush}" Padding="0" Margin="10,0,0,0" FontWeight="Bold"
Text="{Binding Name}"></TextBlock>
</Grid>
</Border>
</ContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
在上面的DataTemplate中,为每个连接的Person创建了一个项目,我想知道如何从ChatClient处理<ScrollViewer x:Name="srcContacts" Grid.Row="0" Margin="0,0,0,0" VerticalScrollBarVisibility="Auto">
<StackPanel>
<ItemsControl ItemsSource="{Binding Path=People, RelativeSource={RelativeSource AncestorType={x:Type chat:ChatClient}}}" x:Name="Contacts">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl>
<Border Style="{StaticResource IsMouseOver}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Top" Height="35" Width="35" Margin="5,0,0,0" BorderBrush="{StaticResource ChatClientPresenceOnlineBrush}" BorderThickness="2" CornerRadius="15">
<Image Height="30" Width="30" Source="Cleo.Windows.Ui.Chat;component/Resources/noavatar.png" StretchDirection="Both" Stretch="Fill">
<Image.Clip>
<EllipseGeometry Center="15,15" RadiusX="15" RadiusY="15" />
</Image.Clip>
</Image>
</Border>
<TextBlock Grid.Column="1" Grid.Row="0" Foreground="{StaticResource ChatClientTextBrush}" Padding="0" Margin="10,0,0,0" FontWeight="Bold" Text="{Binding Name}"></TextBlock>
</Grid>
</Border>
</ContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
的MouseDoubleClick事件,以便ChatClient负责创建ChatWindow ,例子对WPF来说还是不错的。
我一直在阅读附加行为,但很难理解这些将如何适应我想要实现的目标,即我的ChatClient类有一个事件处理程序,当我双击DataTemplate中添加的任何项目时会触发该事件处理程序
任何关于如何实现这一目标的建议都将受到极大的欢迎。
答案 0 :(得分:2)
我建议您在Command
事件中触发MouseDoubleClick
。
要将MouseDoubleClick
事件与Command
相关联并将ClientId
传递给它,您可以使用以下内容:
<ScrollViewer x:Name="srcContacts" Grid.Row="0" Margin="0,0,0,0" VerticalScrollBarVisibility="Auto">
<StackPanel>
<ItemsControl ItemsSource="{Binding Path=People, RelativeSource={RelativeSource AncestorType={x:Type chat:ChatClient}}}" x:Name="Contacts">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl>
<!-- ــــInputBinding For Mouse LeftDoubleClickــــ -->
<ContentControl.InputBindings>
<MouseBinding Gesture="LeftDoubleClick"
Command="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl},Path=DataContext.ClientDoubleClickCommand}"
CommandParameter="{Binding ClientId}"/>
<ContentControl.InputBindings>
<!-- ــــــــــــــــــــــــــــــــــــــــ -->
<Border Style="{StaticResource IsMouseOver}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Top" Height="35" Width="35" Margin="5,0,0,0" BorderBrush="{StaticResource ChatClientPresenceOnlineBrush}" BorderThickness="2" CornerRadius="15">
<Image Height="30" Width="30" Source="Cleo.Windows.Ui.Chat;component/Resources/noavatar.png" StretchDirection="Both" Stretch="Fill">
<Image.Clip>
<EllipseGeometry Center="15,15" RadiusX="15" RadiusY="15" />
</Image.Clip>
</Image>
</Border>
<TextBlock Grid.Column="1" Grid.Row="0" Foreground="{StaticResource ChatClientTextBrush}" Padding="0" Margin="10,0,0,0" FontWeight="Bold" Text="{Binding Name}"></TextBlock>
</Grid>
</Border>
</ContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
然后,您只需在ClientDoubleClickCommand
课程中定义command
ClientChat
(就像其他成员一样People
):
public class ChatClient: INotifyPropertyChanged
{
//-------- Peopole property --------
.
.
.
//-------- ClientDoubleClickCommand --------
ICommand clientDoubleClickCommand;
public ICommand ClientDoubleClickCommand
{
get
{
return clientDoubleClickCommand ??
(clientDoubleClickCommand = new MyCommand(DoThisOnDoubleClick, true));
}
}
private void DoThisOnDoubleClick(object clientId)
{
// Write your target codes (on Mouse Left Double Click) here:
throw new NotImplementedException();
}
//-------- OTHER PROPERTIES AND CODES OF CLASS--------
.
.
.
}
// MyCommand Class: This class is a technique to implement commands easily
public class MyCommand: ICommand
{
private readonly Action<object> _action;
private readonly bool _canExecute;
public MyCommand(Action<object> action, bool canExecute)
{
_action = action;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action(parameter);
}
}
public class People: INotifyPropertyChanged
{
// ClientId Property:
.
.
.
// ClientName Property:
.
.
.
//-------- OTHER PROPERTIES AND CODES OF CLASS--------
.
.
.
}
在此示例中,我假设您的ClientId
类中有People
属性,以保留每个客户端的ID。
现在你有一个People
属性,它是一个客户列表,你就像这样使用它:
<ItemsControl ItemsSource="{Binding Path=People,........
另一方面如果 ItemsControl
DataContext
是»»ChatClient
类
然后我们可以访问其中的ClientDoubleClickCommand
并访问ClientId
中的People
ItemsSource
类ItemsControl
内{{1}阻止:
<MouseBinding Gesture="LeftDoubleClick"
Command="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl},Path=DataContext.ClientDoubleClickCommand}"
CommandParameter="{Binding ClientId}"/>