【问题标题】:WPF Combo box attached property for slection change not firing用于选择更改的 WPF Combobox 附加属性未触发
【发布时间】:2018-11-24 22:32:36
【问题描述】:

为了触发列表框选择更改,我创建了一个附加属性并将其绑定到我的 XAML,如下所示,

<Controls:MetroWindow x:Class="Transport.MainWindow"
          xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
        xmlns:extension="clr-namespace:Transport.Extensions"
        xmlns:local="clr-namespace:Transport
        mc:Ignorable="d"
        Title="CIP Simulator" Height="550" Width="1500"
                      BorderThickness="0" 
                      GlowBrush="Black"
                      ResizeMode="CanResizeWithGrip"
                      ShowMaxRestoreButton="False"
                      WindowTransitionsEnabled="False"
                      WindowStartupLocation="CenterScreen">
 <ComboBox Grid.Column="1" Grid.Row="2" ItemsSource="{Binding Sets}" DisplayMemberPath="Set" 
                  extension:CommandProviders.Command="{Binding SetSelectionChange}"
                  SelectedItem="{Binding SelectedSet}" Grid.ColumnSpan="3"/>

现在附加的属性 def 如下所示:

public class CommandProviders
    {
        public static ICommand GetCommand(DependencyObject depObject)
        {
            return (ICommand)depObject.GetValue(CommandProprtey);
        }

        public static void SetCommand(DependencyObject depobject, ICommand value)
        {
            depobject.SetValue(CommandProprtey, value);
        }

        public static readonly DependencyProperty CommandProprtey =
            DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(CommandProviders), null);
    }

我现在已经创建了公共 I 命令并分配给 relayCommand(这是其他按钮的中继命令)。

 public ICommand SetSelectionChange { get; set; }
 SetSelectionChange = new RelayCommand(commandx =>
                {
                    //Do Something

                });

但这不会触发选择更改!

【问题讨论】:

  • 到目前为止,您已经在源和目标中完成了SetSelectionChange 的处理,但是谁会调用附加的命令? `ICommand SetSelectionChange` 执行方法只有在附加的命令被调用后才会被调用。但我没有看到任何调用附加命令的代码。
  • @user1672994,你是什么意思,附加属性接受从 XAML 分配给它的命令,从 ViewModel 分配 ICommand。这就像您将绑定到按钮的任何其他命令一样。在选择更改时,应触发 Icommand,因为附加属性的类型是 ICommand
  • @Simsons,您通过使用该命令 (SetSelectionChange) 尝试实现的目标是什么?
  • 查看示例实现 - codeproject.com/Tips/692265/WPF-Custom-Attached-Property。因此,在您的情况下,您应该订阅 ComboBox 的 SelectionChanged 事件,并且在处理程序中,如果要在没有参数的情况下发送,则应调用命令为 command?.Invoke(null),如果选择 Item 值,则应调用为 command.Invoke(&lt;&lt;Combobox selected Item&gt;&gt;)
  • 如前所述,您忘记实现一个 PropertyChangedCallback,它在设置附加属性的 ComboBox 处附加一个 SelectionChanged 事件处理程序。

标签: c# wpf dependency-properties attached-properties


【解决方案1】:

如 cmets 中所述,您应该定义 PropertyChangedCallback。下面是订阅combBox Selection Changed 的​​管道代码,并引发了应该触发绑定RelayCommand 的命令。

public class CommandProviders
{
    public static ICommand GetCommand(DependencyObject depObject)
    {
        return (ICommand)depObject.GetValue(CommandProprtey);
    }

    public static void SetCommand(DependencyObject depobject, ICommand value)
    {
        depobject.SetValue(CommandProprtey, value);
    }

    public static readonly DependencyProperty CommandProprtey =
        DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(CommandProviders), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnCommandChanged)));

}


private static void OnCommandChanged
(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    ComboBox cmbBox= (ComboBox)d;
    if (cmbBox != null)     
    {
        cmbBox.SelectionChanged += (sender, eventArgs) => 
           {
               d.GetValue(CommandProprtey)?.Invoke(null);
           }
    }
}

其他几点

为您的示例透视编写此代码。在代码中,SelectionChanged 事件已被订阅,因此您必须了解如何取消订阅该事件,以免导致内存泄漏。

【讨论】:

  • 有道理,附加属性没有回调。
  • 您的意思是安全投射而不是直接投射到 ComboBox 吗?此外,Proprtey 中的拼写错误可能会导致问题。
猜你喜欢
  • 1970-01-01
  • 2018-07-21
  • 2013-03-03
  • 2018-02-15
  • 2018-03-15
  • 2015-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多