WPF 按钮位于数据上下文之外,无法绑定
您好,
我的 有 3 个按钮添加、删除、打开为 RelayCommands >文档视图模型。 下面你可以看到我是如何绑定它们的。当然,这些绑定不起作用,因为数据设置为 ListBox 的 ItemsSource,而按钮位于该列表的外部...
然后我尝试的是在您在代码片段中看到的第一个 StackPanel 处设置 DataContext。
像这样:
但随后出现了一个新问题...现在文档在 ListBox 中不再可见/列出:/
< em>我怎样才能让两者都工作?
<StackPanel Orientation="Vertical" >
<ListBox
Height="100"
Width="Auto"
Focusable="True"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Grid.Row="1"
Name="itemListBox"
BorderThickness="1"
ItemsSource="{Binding DocumentViewModelList}"
>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<!-- xxx -->
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<Button Command="{Binding DeleteDocumentCommand}" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" Content="Delete" />
<Button Command="{Binding AddDocumentCommand}" HorizontalAlignment="Stretch" Content="Add" />
<Button Command="{Binding OpenDocumentCommand}" HorizontalAlignment="Stretch" Content="Open" />
</StackPanel>
</StackPanel>
更新:
我尝试了这个:
<Button Command="{Binding Path=DeleteDocumentCommand, RelativeSource={RelativeSource AncestorType={x:Type DocumentViewModel}}}"
并得到了这个:类型引用找不到名为“DocumentViewModel”的公共类型
我想坚持使用 StackPanel DataContext 解决方案,并以某种方式使 ListBox.ItemsSource 通过与 FindAncestor 的relativeSource 绑定来抓取 DocumentViewModelList。我尝试了一些东西,但没有运气,也许有人可以发布一个不错的片段:)
好吧,我找到了解决方案:
这绑定到当前的 DataContext,即“DocumentViewModelList”,酷!
更新2:
好吧,还有另一个问题,也许如果有人可以提供解决方案,那么我会将此线程标记为解决方案。不想打开一个新线程,因为整个文本+代码片段是相同的...现在的问题是=>选择第一个文档激活按钮。选择任何其他按钮不会激活按钮,为什么?我的 IsSelected 属性的绑定有什么问题?
DocumentViewModel.cs:
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
if (_isSelected == value)
return;
_isSelected = value;
this.RaisePropertyChanged("IsSelected");
}
}
更新2:
这是启用按钮的代码:我做错了什么?我在输出控制台中没有收到任何绑定错误!?
private void DeleteDocument()
{
throw new NotImplementedException();
}
private bool CanDeleteDocument()
{
return (IsSelected == true);
}
private void AddDocument()
{
}
private void OpenDocument()
{
}
public RelayCommand DeleteDocumentCommand
{
get { return _deleteDocumentCommand ?? (_deleteDocumentCommand = new RelayCommand(() => DeleteDocument(), () => CanDeleteDocument())); }
}
public RelayCommand AddDocumentCommand
{
get { return _addDocumentCommand ?? (_addDocumentCommand = new RelayCommand(() => AddDocument())); }
}
public RelayCommand OpenDocumentCommand
{
get { return _openDocumentCommand ?? (_openDocumentCommand = new RelayCommand(() => OpenDocument())); }
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
DocumentViewModelList
是您的DocumentViewModel
的属性吗?通常,我会拥有该窗口的 ViewModel,它将公开 ObservableCollection,其中
T
是您想要在列表中显示的内容。然后,您可以将Window/Page等的DataContext
分配给ViewModel,然后将ListBox
的ItemsSource
绑定到它ObservableCollection
属性。例如,这是我的 ViewModel 的片段。
在 XAML 的代码隐藏中(我通常在构造函数中执行此操作),您可以将其
DataContext
设置为 ViewModel 的新实例。设置窗口的 DataContext 后,您可以绑定
ItemsSource
到公开的属性(我称之为Docs
)希望有帮助。
更新
在按钮的
RelayCommand
中,您是否为CanExecute
谓词指定了某些内容?如果没有,那么我相信RelayCommand
将默认为始终启用。但如果您指定了谓词,请查看其中。您为
IsSelected
属性发布的代码看起来不错。看起来问题出在其他地方。Is the
DocumentViewModelList
a property of yourDocumentViewModel
?Typically, what I would have is a ViewModel for that window which would expose an
ObservableCollection<T>
whereT
is what you want displayed in the list. Then, you can assign the Window/Page/etc.'sDataContext
to the ViewModel, and then bind theItemsSource
of theListBox
to thatObservableCollection<T>
property.For example, here would be a snippet of my ViewModel.
In the code-behind for the XAML, (I usually do it in the constructor), you can set its
DataContext
to a new instance of your ViewModelWith the Window's DataContext set, you can bind the
ItemsSource
to the exposed property (I called itDocs
)Hope that helps.
Update
In the
RelayCommand
for the button, do you have something specified for theCanExecute
predicate? If not, then I believe theRelayCommand
will default to always enabled. But if you have a predicate specified, take a look in there.The code you posted for the
IsSelected
property looks fine. Looks like the problem lies elsewhere.