无法将命令绑定到 HyperlinkButton (Windows Phone 8.1)
Unable to bind a Command to a HyperlinkButton (Windows Phone 8.1)
我正在构建一个使用 MVVM 的应用程序,并尝试将命令绑定到按钮,如本教程所示:
但是,我无法使绑定工作 - 当我单击 HyperlinkButton 时没有任何反应,并且我在 Execute 方法开头设置的断点没有触发。
这是我的视图模型:
public class ArticleListViewModel
{
public IEnumerable<ArticleItem> Items { get; set; }
public async Task PopulateArticles()
{
// ...
}
}
public class ArticleItem
{
public ArticleItem()
{
OpenLinkCommand = new OpenArticleLinkCommand();
}
public ICommand OpenLinkCommand;
public string Url { get; set; }
public string Title { get; set; }
}
OpenArticleLinkCommand.cs:
public class OpenArticleLinkCommand : ICommand
{
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public async void Execute(object parameter)
{
var article = parameter as ArticleItem;
if (article != null)
{
var success = await Launcher.LaunchUriAsync(new Uri(article.Url));
//TODO: handle success/fail
}
}
}
我的视图如下所示:
<UserControl
x:Class="LTNewsFeed.Views.ArticleItemView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:LTNewsFeed.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<ListBox ItemsSource="{Binding}" x:Name="mainListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<HyperlinkButton x:Name="Title"
Content="{Binding Path=Title, Mode=OneWay}"
Command="{Binding OpenLinkCommand}"
Grid.Column="0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</UserControl>
主要Page.xaml:
<Page
x:Class="LTNewsFeed.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:LTNewsFeed"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="using:LTNewsFeed.Views"
xmlns:src="using:LTNewsFeed"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<views:ArticleItemView x:Name="ItemsOnPage" />
</Grid>
</Page>
我在 MainPage.xaml.cs:
中填充视图模型项集合
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
await viewModel.PopulateArticles();
ItemsOnPage.DataContext = viewModel.Items;
}
我尝试过但没有成功的事情:
- 引用
DataContext
并指定 ElementName
,如 this answer 中的建议。
- 将 HyperlinkButton 更改为简单的按钮。
- 将
OpenArticleLinkCommand
移动到与我的 ArticleItem
模型相同的文件中,以防名称空间因某种原因无法识别。
- 在 Google 和 Whosebug 上浏览类似问题 - 在我看来,我所做的一切都与示例中的相同。
如果能为我指明正确的方向,或描述我如何调试此类内容,将不胜感激。
听起来很奇怪,绑定只对属性有效。因此,您需要将命令公开为 属性 而不是字段:
public ICommand OpenLinkCommand { get; set; }
您可以通过查看 Visual Studio 的输出面板注意到这一点,其中在执行时显示错误消息:
Error: BindingExpression path error: 'OpenLinkCommand' property not found
请注意,您会立即遇到另一个问题:您希望命令有一个参数,但您忘记设置一个。由于您显然期望 ArticleItem
作为参数,因此您可以简单地绑定数据上下文:
<HyperlinkButton x:Name="Title"
Content="{Binding Path=Title, Mode=OneWay}"
Command="{Binding OpenLinkCommand}"
CommandParameter="{Binding}"
Grid.Column="0"/>
我正在构建一个使用 MVVM 的应用程序,并尝试将命令绑定到按钮,如本教程所示:
但是,我无法使绑定工作 - 当我单击 HyperlinkButton 时没有任何反应,并且我在 Execute 方法开头设置的断点没有触发。
这是我的视图模型:
public class ArticleListViewModel
{
public IEnumerable<ArticleItem> Items { get; set; }
public async Task PopulateArticles()
{
// ...
}
}
public class ArticleItem
{
public ArticleItem()
{
OpenLinkCommand = new OpenArticleLinkCommand();
}
public ICommand OpenLinkCommand;
public string Url { get; set; }
public string Title { get; set; }
}
OpenArticleLinkCommand.cs:
public class OpenArticleLinkCommand : ICommand
{
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public async void Execute(object parameter)
{
var article = parameter as ArticleItem;
if (article != null)
{
var success = await Launcher.LaunchUriAsync(new Uri(article.Url));
//TODO: handle success/fail
}
}
}
我的视图如下所示:
<UserControl
x:Class="LTNewsFeed.Views.ArticleItemView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:LTNewsFeed.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<ListBox ItemsSource="{Binding}" x:Name="mainListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<HyperlinkButton x:Name="Title"
Content="{Binding Path=Title, Mode=OneWay}"
Command="{Binding OpenLinkCommand}"
Grid.Column="0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</UserControl>
主要Page.xaml:
<Page
x:Class="LTNewsFeed.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:LTNewsFeed"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="using:LTNewsFeed.Views"
xmlns:src="using:LTNewsFeed"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<views:ArticleItemView x:Name="ItemsOnPage" />
</Grid>
</Page>
我在 MainPage.xaml.cs:
中填充视图模型项集合 protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
await viewModel.PopulateArticles();
ItemsOnPage.DataContext = viewModel.Items;
}
我尝试过但没有成功的事情:
- 引用
DataContext
并指定ElementName
,如 this answer 中的建议。 - 将 HyperlinkButton 更改为简单的按钮。
- 将
OpenArticleLinkCommand
移动到与我的ArticleItem
模型相同的文件中,以防名称空间因某种原因无法识别。 - 在 Google 和 Whosebug 上浏览类似问题 - 在我看来,我所做的一切都与示例中的相同。
如果能为我指明正确的方向,或描述我如何调试此类内容,将不胜感激。
听起来很奇怪,绑定只对属性有效。因此,您需要将命令公开为 属性 而不是字段:
public ICommand OpenLinkCommand { get; set; }
您可以通过查看 Visual Studio 的输出面板注意到这一点,其中在执行时显示错误消息:
Error: BindingExpression path error: 'OpenLinkCommand' property not found
请注意,您会立即遇到另一个问题:您希望命令有一个参数,但您忘记设置一个。由于您显然期望 ArticleItem
作为参数,因此您可以简单地绑定数据上下文:
<HyperlinkButton x:Name="Title"
Content="{Binding Path=Title, Mode=OneWay}"
Command="{Binding OpenLinkCommand}"
CommandParameter="{Binding}"
Grid.Column="0"/>