我有一个像以下
的ItemsControl<ItemsControl ItemsSource="{Binding MyClass.Links}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid d:DesignWidth="450" d:DesignHeight="245" Height="Auto" Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="145"/>
<ColumnDefinition Width="Auto" MinWidth="179"/>
</Grid.ColumnDefinitions>
<HyperlinkButton Content="{Binding ViewName}" IsEnabled="{Binding ViewEnabled, Mode=OneWay}" cmd:Click.Command="{Binding DataSource.ViewCommand, Source={StaticResource DataContextProxy}}" cmd:Click.CommandParameter="{Binding}" Margin="4"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
我有一个以下类的ObservableCollection,itemssource被绑定到
public class LinkClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string ViewName { get; set; }
private bool _viewEnabled;
public bool ViewEnabled {
get { return this._viewEnabled; }
set
{
if (value != this._viewEnabled)
{
this._viewEnabled = value;
if (this.PropertyChanged != null)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
this.PropertyChanged(this, new PropertyChangedEventArgs("ViewEnabled"))
);
}
}
}
}
}
当在视图模型中命中命令时,绑定链接的ViewEnabled被设置为false(禁用我正在查看的视图的链接)。问题是,链接实际上没有被禁用(IsEnabled设置为false)。
所以最后的问题是,为什么这不起作用?我是MVVM和silverlight的新手,所以我希望它很简单。
更新
我将ViewEnabled属性设置为true,除了单击按钮的绑定LinkClass,我将其设置为false。它为每个(更改)触发了PropertyChanged事件,但没有更新UI。我使用绑定运行了一个空的转换器,并且在单击链接时也没有被击中,因此PropertyChanged没有正确冒泡(或者我怀疑它应该正常)。
以下是设置我的LinkClass集合的ViewEnabled属性的代码:
public ICommand ViewCommand
{
get {
return new DelegateCommand<object>(param =>
{
this.ViewSelected((LinkClass)param);
});
}
}
public void ViewSelected(LinkClass link)
{
foreach (var containerLink in _myClass.Links)
{
if (containerLink == link)
containerLink.ViewEnabled = false;
else
containerLink.ViewEnabled = true;
}
...other code here
}
答案 0 :(得分:1)
实际上它可能会被禁用但是如果你的ViewCommand
没有注意到该属性,那么你就会陷入困境。特别是因为看起来该命令是一个附加属性。
谷歌搜索让我this post你想看看。
但我个人会查看您CanExecute
的{{1}},并确保仅在ViewCommand
答案 1 :(得分:0)
当我使用MVVM时,在我的属性的setter中,我有一个名为NotifyPropertyChanged()的方法,并且会调用它传递属性名称的字符串值。我不确定Deployment.Current.Dispatcher.BeginInvoke(...)是做什么的,但这个方法总是对我有用。
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler.IsNotNull())
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
所以在我的财产中,我会做类似的事情......
public Nullable<int> UpdatedBy
{
get { return _updatedBy; }
set
{
if (_updatedBy.IsEqualTo(value))
return;
_updatedBy = value;
NotifyPropertyChanged("UpdatedBy");
}
}
另外,只是抓住吸管,但尝试放置{Binding Path = ViewEnabled,...} 希望这会有所帮助。
答案 2 :(得分:0)
根据Jose的建议,我查看了我正在使用的ViewCommand(DelegateCommand)的canExecute方法,但是实现该方法并没有解决问题,因为它只运行一次,而不是在更改时运行。我找到了一个示例,建议使用INotifyPropertyChanged类的PropertyChanged事件处理程序来调用DelegateCommand的RaiseCanExecuteChanged()方法。我为所有LinkClass实例执行了此操作,如此处所示为1,然后将其设置为_myClass.Links:
var link = new LinkClass()
{
...
ViewEnabled = true
};
link.PropertyChanged += new PropertyChangedEventHandler(link_PropertyChanged);
return link;
我这样做了,但无济于事。然后我发现这篇博文:DelegateCommand in Prism loses eventhandler and CanExecute never gets called然后我从Prism切换到RelayCommand类,它起作用了!希望这有助于其他人。
<强>更新强>
实际问题在于使用Prism的 cmd:Click.Command 和 cmd:Click.CommandParameter XAML。正如我在切换到RelayCommand后所做的那样,在xaml中从那里切换到 命令 和 CommandParameter 属性是什么实际上让它工作。