【问题标题】:Handle an event that is inside user control in list view处理列表视图中用户控件内部的事件
【发布时间】:2021-09-14 18:03:25
【问题描述】:

我有一个用户控件列表,每个用户控件都有两个按钮,当我点击它们时,一定会发生一些事情,但我想不在用户控件内部处理这个事件,我想在主页 那么,如何捕获列表视图的选定项用户控件触发的事件?

后面的用户控制代码:

 public sealed partial class TestingUerControl : UserControl
{
    public TestingUerControl()
    {
        this.InitializeComponent();
    }

    public event EventHandler FirstButtonEvent;
    public event EventHandler SecondButtonEvent;

    private void firstButton_Click(object sender, RoutedEventArgs e)
    {
        //Some stuff of code
        FirstButtonEvent?.Invoke(this, new EventArgs());
    }

    private void secondButton_Click(object sender, RoutedEventArgs e)
    {
        //Some stuff of code
        SecondButtonEvent?.Invoke(this, new EventArgs());
    }
}

主页 xaml 标记:

  <ListView x:Name="listUserControl"
              Width="100"
              Header="400">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="model:MyModel">
                <userControl:TestingUerControl/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

我用了这个说法:

((TestingUerControl)listUserControl.SelectedItem).FirstButtonEvent += OnFirstButtonEvent;

但这不起作用我只能将 SelectedItem 转换为 MyModel 类 那么如何才能到达列表视图的选定用户控件的“FirstButtonEvent”和“SecondButtonEvent”

【问题讨论】:

  • 控件应该公开两个绑定到 MyModel 类的 ICommand 属性的 ICommand 属性。
  • 我想在不使用 mvvm 的情况下做到这一点,如果你给我看一些代码,我将不胜感激

标签: wpf xaml uwp uwp-xaml


【解决方案1】:

使用命令和 MVVM 的方式更可取,但您也可以使用自定义 RoutedEvent 而不是 Event

public sealed partial class TestingUerControl : UserControl
{
    public TestingUerControl()
    {
        this.InitializeComponent();
    }

    public static readonly RoutedEvent FirstButtonEvent = EventManager.RegisterRoutedEvent(
        nameof(FirstButton), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TestingUerControl));

    public event RoutedEventHandler FirstButton
    {
        add { AddHandler(FirstButtonEvent, value); }
        remove { RemoveHandler(FirstButtonEvent, value); }
    }

    private void firstButton_Click(object sender, RoutedEventArgs e)
    {
        //Some stuff of code
        RaiseEvent(new RoutedEventArgs(TestingUerControl.FirstButtonEvent));
    }

    private void secondButton_Click(object sender, RoutedEventArgs e)
    {
        //See first btn
    }
}

然后在 XAML 中分配一个事件处理程序:

<ListView x:Name="listUserControl" Width="100" Header="400">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="model:MyModel">
            <userControl:TestingUerControl FirstButton="OnFirstButton_Click"/>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

【讨论】:

  • 这对我不起作用,因为我在做 UWP 项目,这种应用程序不支持 EventManager、RoutingStrategy 类
  • 我用这个解决了我的问题:link
【解决方案2】:

使用 MVVM:

public class TestCommand : ICommand
{
    Action<object> _execute;
    Func<object, bool> _canExecute;


    public TestCommand(Action<object> execute)
      : this(execute, DefaultCanExecute)
    {
    }

    public TestCommand(Action<object> execute, Func<object, bool> canExecute)
    {
        if (execute == null)
        {
            throw new ArgumentNullException("execute");
        }

        if (canExecute == null)
        {
            throw new ArgumentNullException("canExecute");
        }

        this._execute = execute;
        this._canExecute = canExecute;
    }

    public event EventHandler CanExecuteChanged
    {
        add
        {
            CommandManager.RequerySuggested += value;
        }
        remove
        {
            CommandManager.RequerySuggested -= value;
        }
    }

    public bool CanExecute(object parameter)
    {
        if (_canExecute != null)
        {
            return _canExecute(parameter);
        }
        else
        {
            return false;
        }
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }

    private static bool DefaultCanExecute(object parameter)
    {
        return true;
    }

}

public class MyModel 
{
    public MyModel()
    {
        FirstButtonCmd = new TestCommand(OnFirstButtonCmd);
        SecondButtonCmd = new TestCommand(OnSecondButtonCmd);
    }
    
    public ICommand FirstButtonCmd{get;set;}
    public ICommand SecondButtonCmd{get;set;}
    
    private void OnFirstButtonCmd()
    {
        //click first button
    }
    
    private void OnSecondButtonCmd()
    {
        //click second button
    }
}

TestingUerControl.xaml

<Button Click={Binding FirstButtonCmd}></Button>
<Button Click={Binding SecondButtonCmd}></Button>

TestingUerControl.xaml.cs

public sealed partial class TestingUerControl : UserControl
{
    public TestingUerControl()
    {
        this.InitializeComponent();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 2011-02-25
    • 1970-01-01
    • 2010-09-10
    • 2012-06-27
    • 2011-03-29
    • 2017-12-05
    相关资源
    最近更新 更多