New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binding in Command doesn't work #320

Open
chenyj796 opened this Issue Feb 3, 2019 · 3 comments

Comments

Projects
None yet
3 participants
@chenyj796
Copy link

chenyj796 commented Feb 3, 2019

  • .NET Core Version: (3.0 Preview1)
  • Windows version: (windows 10)
  • Does the bug reproduce also in WPF for .NET Framework 4.6.1?: yes

Problem description:
I have a MenuModel:

public class MenuModel : ModelBase
{
    public int Id { get; }
    public int ParentId { get; }

    private string name;
    public string Name
    {
        get { return name; }
        set { if (name != value) { name = value; this.OnPropertyChanged(); } }
    }

    private string entry;
    public string Entry
    {
        get { return entry; }
        set { if (entry != value) { entry = value; this.OnPropertyChanged(); } }
    }

    public MenuModel(int id, int parentId)
    {
        this.Id = id;
        this.ParentId = parentId;
    }
}

and a command:

public class TestCommand : DependencyObject, ICommand
{
    public event EventHandler CanExecuteChanged;

    public MenuModel Model
    {
        get { return (MenuModel)GetValue(ModelProperty); }
        set { SetValue(ModelProperty, value); }
    }

    public static readonly DependencyProperty ModelProperty =
        DependencyProperty.Register("Model", typeof(MenuModel), typeof(TestCommand), new PropertyMetadata(null));


    public bool CanExecute(object parameter)
    {
        ......
    }

    public void Execute(object parameter)
    {
        ......
    }
}

In xaml file, I bind them to the TabControl's ItemTemplate:

<TabControl.ItemTemplate>
    <DataTemplate>
        <Button Content="{Binding Title}" Margin="3,1,0,0">
            <Button.Command>
                <local:TestCommand Model="{Binding}" />
            </Button.Command>
        </Button>
    </DataTemplate>
</TabControl.ItemTemplate>

Actual behavior:
The binding of TestCommand.Model returns null.
Perhaps it is caused by the type of Command property in Button class is ICommand (which is a interface)

Expected behavior:
Return the MenuModel object

Minimal repro:

@chenyj796 chenyj796 changed the title Binding in DataTemplate and Command doesn't work Binding in Command doesn't work Feb 4, 2019

@stevenbrix stevenbrix added this to the Future milestone Feb 13, 2019

@stevenbrix

This comment has been minimized.

Copy link
Member

stevenbrix commented Feb 13, 2019

Thanks for filing this issue @chenyj796. I believe there a few reasons why this wouldn't work:

  1. Your Command type is not a FrameworkElement, so there is no DataContext to use as the Source of the Binding
  2. The Command is not in the Visual Tree. This means using ElementName syntax doesn't work, nor will DataContext propagate even if you make the Command derive from FrameworkElement.

You could try looking at this StackOverflow issue and see if you could do something similar to workaround this.

@walterlv

This comment has been minimized.

Copy link
Contributor

walterlv commented Feb 14, 2019

@chenyj796 Maybe you're suffering from this issue:

从你的名字推断,你可能可以阅读中文,所以放出中文链接:

@chenyj796

This comment has been minimized.

Copy link
Author

chenyj796 commented Feb 14, 2019

Thanks stevenbrix and walterlv, I got it.
Now I create a new class which contains the MenuModel and Command.

    public class MenuNode : TreeNode<MenuNode, MenuModel>
    {
        public MenuNode(MenuModel content) : base(content)
        {
            this.Command = new MenuCommand(this);
        }

        public ICommand Command { get; }
    }

and use the MenuNode for binding

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment