【问题标题】:Button Command get not fired按钮命令未被触发
【发布时间】:2014-01-29 17:45:34
【问题描述】:

我有一个奇怪的情况。 我正在为 WINRT 开发一个应用程序,并且在命令绑定方面遇到了一些问题。这是 xaml 的一部分:

    <control:ItemsHub ItemsSource="{Binding Categories}">
        <control:ItemsHub.SectionHeaderTemplate>
            <DataTemplate>
                <Button Command="{Binding CategoryNavigationCommand}" Margin="5,0,0,10" Content="{Binding Header}"/>
            </DataTemplate>
        </control:ItemsHub.SectionHeaderTemplate>
    </control:ItemsHub>

这是我的 ViewModel:

    public CategorySectionViewModel(IRecipeService recipeService, INavigationService navigationService, RecipeTreeItemDto treeItem)
    {
        ...
        CategoryNavigationCommand = new DelegateCommand(NavigateToCategory);
        ...
    }


    private string _header;

    public string Header
    {
        get { return _header; }
        set { SetProperty(ref _header, value); }
    }

    public DelegateCommand CategoryNavigationCommand { get; private set; }


    private void NavigateToCategory()
    {
        _navigationService.Navigate("CategoryHub", _recipeTreeItemDto.NodePath);
    }

我在输出窗口中没有收到任何绑定错误,并且“标题”也显示在按钮中。但是命令不会被解雇,我点击它!我做错了什么?

也许是因为我创建了一个自定义 HubControl。使用此控件,我可以为 HubSection-Header 和 HubSection-Content 附加 ItemSource 和 ItemTemplate。也许正因为如此,一些绑定丢失了?

这是我的自定义集线器控件:

public class ItemsHub : Hub
{
    public DataTemplate ItemTemplate
    {
        get { return (DataTemplate)GetValue(ItemTemplateProperty); }
        set { SetValue(ItemTemplateProperty, value); }
    }

    public IList ItemsSource
    {
        get { return (IList)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }

    public HubSection SpotlightSection
    {
        get { return (HubSection)GetValue(SpotlightSectionProperty); }
        set { SetValue(SpotlightSectionProperty, value); }
    }

    public DataTemplate SectionHeaderTemplate
    {
        get { return (DataTemplate)GetValue(SectionHeaderTemplateProperty); }
        set { SetValue(SectionHeaderTemplateProperty, value); }
    }

    public static readonly DependencyProperty ItemTemplateProperty =
        DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(ItemsHub), new PropertyMetadata(null, ItemTemplateChanged));

    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register("ItemsSource", typeof(IList), typeof(ItemsHub), new PropertyMetadata(null, ItemsSourceChanged));

    public static readonly DependencyProperty SpotlightSectionProperty =
        DependencyProperty.Register("SpotlightSection", typeof(HubSection), typeof(ItemsHub), new PropertyMetadata(default(HubSection), SpotlightSectionChanged));

    public static readonly DependencyProperty SectionHeaderTemplateProperty =
        DependencyProperty.Register("SectionHeaderTemplate", typeof(DataTemplate), typeof(ItemsHub), new PropertyMetadata(default(DataTemplate), HeaderTemplateChanged));

    private static void SpotlightSectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ItemsHub hub = d as ItemsHub;
        if (hub != null)
        {
            bool hubContainsSpotLight = hub.Sections.Contains(hub.SpotlightSection);
            if (hub.SpotlightSection != null && !hubContainsSpotLight)
            {
                hub.Sections.Add(hub.SpotlightSection);
            }
            if (hub.SpotlightSection == null && hubContainsSpotLight)
            {
                hub.Sections.Remove(hub.SpotlightSection);
            }
        }
    }

    private static void HeaderTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ItemsHub hub = d as ItemsHub;
        if (hub != null)
        {
            DataTemplate template = e.NewValue as DataTemplate;
            if (template != null)
            {
                // Apply template
                foreach (var section in hub.Sections.Except(new List<HubSection> { hub.SpotlightSection }))
                {
                    section.HeaderTemplate = template;
                }
            }
        }
    }

    private static void ItemTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ItemsHub hub = d as ItemsHub;
        if (hub != null)
        {
            DataTemplate template = e.NewValue as DataTemplate;
            if (template != null)
            {
                // Apply template
                foreach (var section in hub.Sections.Except(new List<HubSection> { hub.SpotlightSection }))
                {
                    section.ContentTemplate = template;
                }
            }
        }
    }

    private static void ItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ItemsHub hub = d as ItemsHub;
        if (hub != null)
        {
            IList items = e.NewValue as IList;
            if (items != null)
            {
                var spotLightSection = hub.SpotlightSection;
                hub.Sections.Clear();

                if (spotLightSection != null)
                {
                    hub.Sections.Add(spotLightSection);
                }

                foreach (var item in items)
                {
                    HubSection section = new HubSection();
                    section.DataContext = item;
                    section.Header = item;
                    DataTemplate headerTemplate = hub.SectionHeaderTemplate;
                    section.HeaderTemplate = headerTemplate;

                    DataTemplate contentTemplate = hub.ItemTemplate;
                    section.ContentTemplate = contentTemplate;

                    hub.Sections.Add(section);
                }
            }
        }
    }

}

感谢您的帮助!

【问题讨论】:

  • 尝试使用 Command="{Binding Path=DataContext.CategoryNavigationCommand}
  • @jcrada 然后我变成一个绑定错误(错误:BindingExpression 路径错误:在 'WinRTApp.ViewModels.CategorySectionViewModel、WinRTApp、Version=1.0.0.0、Culture=neutral、PublicKeyToken 上找不到'DataContext'属性=null'. BindingExpression: Path='DataContext.CategoryNavigationCommand' DataItem='WinRTApp.ViewModels.CategorySectionViewModel, WinRTApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; 目标元素是 'Windows.UI.Xaml.Controls .Button' (Name='null'); 目标属性是 'Command' (type 'ICommand'))
  • Command="{Binding Path=DataContext.CategoryNavigationCommand}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type localSource:ItemsHub}} localSource 应定义为 xmlns:localSource="clr-namespace :MyProject.library"
  • AncestorType 在 WinRT 中不可用

标签: c# .net xaml windows-runtime winrt-xaml


【解决方案1】:

我找到了解决方案!我不知道为什么,但是集线器控件的部分标题默认情况下不是交互式的!因此,当我在自定义 ItemHub-Control 中分配 itemsource 时,我必须将交互性设置为 true。

这是我在 ItemsHub 控件中所做的更改:

    private static void ItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ItemsHub hub = d as ItemsHub;
        if (hub != null)
        {
            IList items = e.NewValue as IList;
            if (items != null)
            {
                var spotLightSection = hub.SpotlightSection;
                hub.Sections.Clear();

                if (spotLightSection != null)
                {
                    hub.Sections.Add(spotLightSection);
                }

                foreach (var item in items)
                {
                    HubSection section = new HubSection();
                    DataTemplate headerTemplate = hub.SectionHeaderTemplate;
                    section.HeaderTemplate = headerTemplate;

                    DataTemplate contentTemplate = hub.ItemTemplate;
                    section.ContentTemplate = contentTemplate;

                    section.DataContext = item;
                    section.Header = item;

                    //This line fixed my problem.
                    section.IsHeaderInteractive = true;

                    hub.Sections.Add(section);
                }
            }
        }

【讨论】:

    【解决方案2】:

    您可以使用以下绑定表达式

    Command="{Binding CategoryNavigationCommand,RelativeSource={RelativeSource AncestorType=XYX}}"

    而 XYZ 是您放置 ItemsHub 的控件类型

    【讨论】:

    • 我认为 AncestorType 在 WinRT/XAML 中不可用。
    • 真实故事... AncestorType 在 WINRT 中不可用 :(
    猜你喜欢
    • 2012-01-15
    • 2016-06-12
    • 2010-12-19
    • 2014-02-16
    • 2018-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多