Home > OS >  How to raise a host event from a nested control event
How to raise a host event from a nested control event

Time:06-01

So, I have a listbox in wpf that contains as a template (windows forms user control) using WindowsFormsHost,o do this, I additionally created my own host (UserControl3Host), which stores the dependency properties and the windows forms user control event property,see code

Host

public class UserControl3Host : WindowsFormsHost
{
    private readonly UserControl3 userControl = new UserControl3() { Title = string.Empty, 
    Date = string.Empty };
    public delegate void expandedDel2(object sender);       
    public UserControl3Host()
    {
        Child = userControl;
        ConditionalClick  = new RoutedEventHandler(userControl.label1_Click);
    }
    /// <summary>
    /// Заголовок контрола.
    /// </summary>        
    /// <summary>
    /// Заголовок контрола.
    /// </summary>
    public event RoutedEventHandler ConditionalClick
    {
        add
        {
            AddHandler(ConditionalClickEvent, value);
        }
        remove
        {
            RemoveHandler(ConditionalClickEvent, value);
        }
    }
    public string Title
    {
        get => (string)GetValue(TitleProperty);
        set => SetValue(TitleProperty, value);
    }
    public string Date
    {
        get => (string)GetValue(DateProperty);
        set => SetValue(DateProperty, value);
    }
    public static readonly RoutedEvent ConditionalClickEvent = 
   EventManager.RegisterRoutedEvent(
   name: "ConditionalClick",
   routingStrategy: RoutingStrategy.Tunnel,
   handlerType: typeof(RoutedEventHandler),
   ownerType: typeof(UserControl3Host));  

    public static readonly DependencyProperty TitleProperty =
        DependencyProperty.Register(nameof(Title), typeof(string), typeof(UserControl3Host), 
     new PropertyMetadata(string.Empty, OnTitleChanged, OnCoerceTitle));



    public static readonly DependencyProperty DateProperty =
       DependencyProperty.Register(nameof(Date), typeof(string), typeof(UserControl3Host), new 
  PropertyMetadata(string.Empty, OnDateChanged, OnCoerceTitle));

    private static void OnDateChanged(DependencyObject d, DependencyPropertyChangedEventArgs 
   e)
    {
        UserControl3Host host = (UserControl3Host)d;
        host.userControl.Date = e.NewValue.ToString();
    }

    private static void OnTitleChanged(DependencyObject d, DependencyPropertyChangedEventArgs 
    e)
    {
        UserControl3Host host = (UserControl3Host)d;
        host.userControl.Title = e.NewValue.ToString();
    }
    private static object OnCoerceTitle(DependencyObject d, object baseValue)
    {
        return baseValue ?? string.Empty;
    }
   
  }
 } 

The host itself is located in the wpf element(Listbox)

Xaml

    <UserControl x:Class="WindowsFormsApp12.UserControl4"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:WindowsFormsApp12"
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800">
       <ListBox.ItemTemplate>
            <DataTemplate DataType="local:Line">
                <Border Style="{StaticResource MessageBorder}" HorizontalAlignment="Stretch">
                    <StackPanel Orientation="Vertical" MouseDown="StackPanel_MouseDown">
                        <local:UserControl3Host  Title="{Binding Name}" Date="{Binding Date}" 
                    ConditionalClick="UserControl3Host_ConditionalClick"> 
                    </local:UserControl3Host>
                    </StackPanel>
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
  </Border>
 </UserControl>

xaml.cs

public partial class UserControl4 : System.Windows.Controls.UserControl
{     
    public UserControl4()
    {          
        InitializeComponent();           
    }
    public delegate void expandedDel(object sender);

    public event expandedDel isCollapsed;                      
    private void UserControl3Host_ConditionalClick(object sender, RoutedEventArgs e)
    {
        if (isCollapsed != null)
        {
            isCollapsed(this);
        }
    }
}

Code Windows forms element

namespace WindowsFormsApp12
{
public partial class UserControl3 : UserControl
{
    public readonly UserControl5 userControl2 = new UserControl5() { };
    #region Propertyies
    public UserControl3()
    {
        InitializeComponent();
      
    }      
    private string _title;
    private string _date;
    private Image _image;
    private Color _iconBack;
    [Category("Custom Props")]
    public string Title
    {
         get {return _title; }
         set {_title = value; label1.Text = value; }
    }
    [Category("Custom Props")]
    public string Date
    {
        get { return _date; }
        set { _date = value; label2.Text = value; }
    }
    [Category("Custom Props")]
    public Image Image
    {
        get { return _image; }
        set { _image = value;pictureBox1.Image = value; }
    }
    [Category("Custom Props")]
    public Color IconBackGround
    {
        get { return _iconBack; }
        set { _iconBack = value; panel1.BackColor =value ; }
    }

    #endregion
    public delegate void CallFormMethod(object obj,string text); //делегат
    public event CallFormMethod onButtonClick;    
    private void UserControl3_MouseEnter(object sender, EventArgs e)
    {
        this.BackColor = Color.FromArgb(30, 35, 40);
    }
   
    private void UserControl3_MouseLeave_1(object sender, EventArgs e)
    {
       
        this.BackColor = Color.FromArgb(50, 50, 50);
    }

   public void label1_Click(object sender, EventArgs e)
    {
        
        onButtonClick(this,label1.Text);
        
    }

    public void label2_Click(object sender, EventArgs e)
    {
        onButtonClick(this, label1.Text);
    }

    public void pictureBox1_Click(object sender, EventArgs e)
    {
        onButtonClick(this, label1.Text);
    }

    public void panel2_Click(object sender, EventArgs e)
    {
        onButtonClick(this, label1.Text);
    }

    private void UserControl3_Click(object sender, EventArgs e)
    {
        onButtonClick(this, label1.Text);
    }
 }

Now about the problem itself! When launching the program and clicking on the user control in the listbox. Events occur in label click, panel click...(Windows forms events). I need that event work in wpf main window with handler.

 private void UserControl3Host_ConditionalClick(object sender, RoutedEventArgs e)
        {
            if (isCollapsed != null)
            {
                isCollapsed(this);
            }
        }  

i try to use in my xaml ConditionalClick="UserControl3Host_ConditionalClick"> and after what
ConditionalClick = new RoutedEventHandler(userControl.label1_Click) in my host where conditional click was created. I dont know, how iw works. Maybe you know ,how i can catch event or raise event in my windows forms control

CodePudding user response:

Handle the events for UserControl3 in your WindowsFormsHost and raise your ConditionalClick event from the event handlers for the Windows Forms events by calling RaiseEvent(new RoutedEventArgs(ConditionalClickEvent)):

public UserControl3Host()
{
    Child = userControl;
    userControl.label1.Click  = (ss, ee) => RaiseEvent(new RoutedEventArgs(ConditionalClickEvent));
}
  • Related