C# 在自定义控件中处理来自DataTemplate的事件
我正在编写一个WPF客户端,并创建了一个自定义聊天控件,该控件将在客户端中使用。聊天控件由一个聊天客户端组成,该客户端处理加入和退出聊天服务的操作,并根据以下XAML显示已连接用户的列表:C# 在自定义控件中处理来自DataTemplate的事件,c#,wpf,events,user-controls,C#,Wpf,Events,User Controls,我正在编写一个WPF客户端,并创建了一个自定义聊天控件,该控件将在客户端中使用。聊天控件由一个聊天客户端组成,该客户端处理加入和退出聊天服务的操作,并根据以下XAML显示已连接用户的列表: <Style TargetType="{x:Type chat:ChatClient}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate Tar
<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>
这在聊天程序集中的ResourceDictionary中定义,ChatClient作为控件添加到主应用程序窗口中
这一切都很棒,当我运行应用程序时,它会连接到聊天服务器,我会在主窗口右侧看到一个漂亮的面板,上面有一个连接用户的列表
好的,我的问题与上面XAML中的以下部分特别相关:
<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>
在上面的DataTemplate中,为每个连接的人创建了一个项目,我想知道如何从ChatClient处理ContentControl
的MouseDoubleClick事件,这样ChatClient将负责创建ChatWindow,对于WPF来说,这些示例还是很新的
我一直在阅读附加的行为,但很难理解这些行为如何与我希望实现的目标相适应,即我的ChatClient类有一个事件处理程序,当我双击DataTemplate中添加的任何项目时,该事件处理程序将被触发
任何关于如何实现这一点的建议都将被广泛接受。我建议您在
鼠标双击事件上启动命令
要将MouseDoubleClick
事件连接到命令
并将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>
<ItemsControl ItemsSource="{Binding Path=People,........
在本例中,我假设在People
类中有一个ClientId
属性来保存每个客户机的id
现在您有了一个People
属性,它是一个客户列表,您使用它时是这样的:
<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>
<ItemsControl ItemsSource="{Binding Path=People,........
请详细说明您的答案,ChatClient控件如何绑定到事件或命令?我使用的是没有ItemsControl的ScrollViewer,您的解决方案如何与此匹配?你能更清楚地解释一下DataContext.ClientDoubleClickCommand吗?@Neil,我编辑了答案并在其中为你解释了更多。我建议你在你的项目中使用清晰的MVVM
模式。这太棒了,谢谢你,这是一种魅力,当我遇到这样的事情时,我永远不会停止对WPF的力量感到惊讶。我确实得做个小调