WPF依赖项属性未使用绑定触发

时间:2017-09-13 14:33:23

标签: c# wpf dependency-properties icommand

我有一个班级:

public class CommandHamburgerMenu : FrameworkElement, ICommand
{
    public HamburgerMenuItem Item
    {
        get { return (HamburgerMenuItem)GetValue(ItemProperty); }
        set { SetValue(ItemProperty, value); }
    }

    public static readonly DependencyProperty ItemProperty =
        DependencyProperty.Register("Item", typeof(HamburgerMenuItem), typeof(CommandHamburgerMenu), new UIPropertyMetadata(null, new PropertyChangedCallback(ItemChanged)));

    private static void ItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        CommandHamburgerMenu commandHamburgerMenu = (CommandHamburgerMenu)d;
    }

    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        if (this.Item != null)
        {
            if (this.Item == MainWindow.Instance.itemHome) MessageBox.Show("Home item");
            else if (this.Item == MainWindow.Instance.itemSearch) MessageBox.Show("Search item");
            else MessageBox.Show("Other");
        }
        else
        {
            MessageBox.Show("Item is null!");
        }
    }
}

和XAML代码:

<HamburgerMenu:HamburgerMenu MenuIconColor="Black" SelectionIndicatorColor="Black" MenuItemForeground="Black" HorizontalAlignment="Left">
    <HamburgerMenu:HamburgerMenu.Background>
        <SolidColorBrush Color="{Binding Source={x:Static properties:Settings.Default}, Path=ColorHighlight, Mode=TwoWay}" />
    </HamburgerMenu:HamburgerMenu.Background>
    <HamburgerMenu:HamburgerMenuItem x:FieldModifier="public" x:Name="itemHome" Icon="Assets/home.png" Text="Home">
        <HamburgerMenu:HamburgerMenuItem.SelectionCommand>
            <commands:CommandHamburgerMenu Tag="{Binding ElementName=itemHome, Path=Text}" />
        </HamburgerMenu:HamburgerMenuItem.SelectionCommand>
    </HamburgerMenu:HamburgerMenuItem>
    <HamburgerMenu:HamburgerMenuItem x:FieldModifier="public" x:Name="itemSearch" Icon="Assets/search.png" Text="Search">
        <HamburgerMenu:HamburgerMenuItem.SelectionCommand>
            <commands:CommandHamburgerMenu Tag="{Binding ElementName=itemHome, Path=Text}" />
        </HamburgerMenu:HamburgerMenuItem.SelectionCommand>
    </HamburgerMenu:HamburgerMenuItem>
    <HamburgerMenu:HamburgerMenuItem x:FieldModifier="public" x:Name="itemFavorite" Icon="Assets/favorite.png" Text="Likes"/>
    <HamburgerMenu:HamburgerMenuItem x:FieldModifier="public" x:Name="itemList" Icon="Assets/list.png" Text="Lists"/>
    <HamburgerMenu:HamburgerMenuItem x:FieldModifier="public" x:Name="itemPerson" Icon="Assets/person.png" Text="Profile"/>
</HamburgerMenu:HamburgerMenu>

HamburgerMenu是取自here的控件,属性SelectionCommand是ICommand类型的依赖属性,它通过点击汉堡菜单项来触发。但是当app启动时,Item属性为null,而ItemChanged没有触发。它仅在从后面的代码手动设置Item属性后触发。为什么呢?

1 个答案:

答案 0 :(得分:0)

只有在依赖属性的值实际更改时才会调用依赖项属性的PropertyChangedCallback

最初没有为依赖项属性的默认值调用一次。

但是你当然可以自己调用这个方法,例如在类的构造函数中:

public class CommandHamburgerMenu : FrameworkElement, ICommand
{
    public CommandHamburgerMenu()
    {
        ItemChanged(this, new DependencyPropertyChangedEventArgs(CommandHamburgerMenu.ItemProperty, null, null));
    }

    public HamburgerMenuItem Item
    {
        get { return (HamburgerMenuItem)GetValue(ItemProperty); }
        set { SetValue(ItemProperty, value); }
    }

    public static readonly DependencyProperty ItemProperty =
        DependencyProperty.Register("Item", typeof(HamburgerMenuItem), typeof(CommandHamburgerMenu), new UIPropertyMetadata(null, new PropertyChangedCallback(ItemChanged)));

    private static void ItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        CommandHamburgerMenu commandHamburgerMenu = (CommandHamburgerMenu)d;
    }

    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        if (this.Item != null)
        {
            if (this.Item == MainWindow.Instance.itemHome) MessageBox.Show("Home item");
            else if (this.Item == MainWindow.Instance.itemSearch) MessageBox.Show("Search item");
            else MessageBox.Show("Other");
        }
        else
        {
            MessageBox.Show("Item is null!");
        }
    }
}