您好
我的 DocumentViewModel 中有3个按钮添加,删除,打开为 RelayCommands 。 下面你看看我是如何约束他们的。当然,这些绑定不起作用,因为数据设置为 ListBox 的 ItemsSource ,按钮在之外 ...
我尝试的是在我的代码片段中看到的第一个StackPanel上设置DataContext。
像这样:<StackPanel DataContext="{Binding DocumentViewModelList}" >
然后又出现了一个新问题......现在文件在列表框中不再可见/列出了:/
我如何才能同时工作?
<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。我尝试了一些东西,但没有运气,也许有人可以发一个漂亮的片段:)
好的,我找到了解决方案:<ListBox ItemsSource="{Binding}" ..
。
这是绑定到当前的DataContext,即“DocumentViewModelList”很酷!
更新2:
好吧还有另一个问题,也许如果有人可以提供解决方案,那么我将此线程标记为解决方案。不想打开新线程,因为整个文本+代码片段是相同的...现在问题是=&gt;选择第一个文档激活按钮。选择任何其他按钮不会激活按钮,为什么?我的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())); }
}
答案 0 :(得分:2)
DocumentViewModelList
属性是DocumentViewModel
吗?
通常情况下,我所拥有的是该窗口的ViewModel,它会公开ObservableCollection<T>
,其中T
是您希望在列表中显示的内容。然后,您可以将Window / Page /等DataContext
分配给ViewModel,然后将ItemsSource
的{{1}}绑定到该ListBox
属性。
例如,这里将是我的ViewModel的片段。
ObservableCollection<T>
在XAML的代码隐藏中,(我通常在构造函数中执行),您可以将其public class SomeViewModel
{
public ObservableCollection<SingleDocumentViewModel> Docs {get; private set; }
// other properties can go here
}
设置为ViewModel的新实例
DataContext
使用Window的DataContext集,您可以将public AwesomeDocumentList()
{
this.DataContext = new SomeViewModel();
// the rest of the constructor
}
绑定到公开的属性(我称之为ItemsSource
)
Docs
希望有所帮助。
<强>更新强>
在按钮的<ListBox ItemsSource="{Binding Docs}" ... />
中,您是否为RelayCommand
谓词指定了一些内容?如果没有,那么我相信CanExecute
将默认始终启用。但如果您指定了谓词,请查看其中。
您为RelayCommand
媒体资源发布的代码看起来不错。看起来问题出在其他地方。