在自定义控件中处理来自DataTemplate的事件

时间:2015-12-29 13:46:40

标签: c# wpf events user-controls

我正在编写一个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中添加的任何项目时会触发该事件处理程序

任何关于如何实现这一目标的建议都将受到极大的欢迎。

1 个答案:

答案 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 ItemsSourceItemsControl内{{1}阻止:

<MouseBinding Gesture="LeftDoubleClick"
              Command="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl},Path=DataContext.ClientDoubleClickCommand}" 
              CommandParameter="{Binding ClientId}"/>