问题描述
我有一个绑定到 DataGrid 的 MeetingViewModelList .每个 MeetingViewModel 都有一个 DocumentViewModelList 绑定到DataGrid的 DataGridTemplateColumn 中的 ListBox .
I have a MeetingViewModelList bound to a DataGrid.Each MeetingViewModel has a DocumentViewModelList bound to a ListBox within the DataGrid`s DataGridTemplateColumn.
DocumentViewModel的IsSelected属性绑定到ListBox的Item属性IsSelected.
The IsSelected property of the DocumentViewModel is bound to the ListBox`s Item property IsSelected.
我在输出控制台中没有任何绑定错误.
DocumentViewModel中的删除文档按钮将在其CanExecute方法中检查以下内容:
The delete document button in the DocumentViewModel checks in its CanExecute Method this:
private bool CanDeleteDocument()
{
return _isSelected;
}
当我在列表框中选择 FIRST 项时,将启用删除"按钮.当我在列表框中选择第二,第三等项目时,总是禁用删除"按钮.
When I select the FIRST Item in the ListBox, the Delete button is enabled.When I selected the 2nd,3rd etc. Item in the ListBox the Delete button is ALWAYS disabled.
我尝试仅粘贴重要代码并裁剪其他内容:
I try to paste only the important code and cropped other stuff:
我刚刚尝试仅使用ListBox重建场景-而不是DataGrid的一部分-而我得到了相同的行为:/
I have just tried to rebuild the scenario with just a ListBox -not being part of a DataGrid- and I get the same behavior :/
任何提示我都会很高兴:)
I would be pleased about any hint :)
XAML :
<DataGrid VirtualizingStackPanel.VirtualizationMode="Recycling"
ScrollViewer.CanContentScroll="False"
CanUserResizeRows="True"
VerticalScrollBarVisibility="Auto"
ItemsSource="{Binding MeetingViewModelList}"
AutoGenerateColumns="False"
x:Name="DailyGrid"
Height="580"
SelectionMode="Single"
CanUserSortColumns="False"
Background="#FF2DCE2D"
CanUserAddRows="False"
HeadersVisibility="All"
RowHeaderWidth="40"
RowHeight="200" >
<!--Content-->
<DataGridTemplateColumn Width="0.5*" Header="Content">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Helper:RichTextBox LostFocus="RTFBox_LostFocus" VerticalScrollBarVisibility="Auto" x:Name="RTFBox" Text="{Binding Content,IsAsync=True}" AcceptsReturn="True" AutoWordSelection="False" AllowDrop="False" SelectionBrush="#FFAC5BCB" HorizontalScrollBarVisibility="Hidden">
<Helper:RichTextBox.TextFormatter>
<Helper:RtfFormatter />
</Helper:RichTextBox.TextFormatter>
</Helper:RichTextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!--Documents-->
<DataGridTemplateColumn Visibility="{Binding Source={StaticResource spy}, Path=DataContext.DocumentsVisible}" IsReadOnly="True" Width="125" Header="Attachments">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Background="Green" DataContext="{Binding DocumentViewModelList}" Orientation="Vertical" >
<ListBox SelectionMode="Single" VirtualizingStackPanel.IsVirtualizing="False"
Height="100"
Width="Auto"
Focusable="True"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Grid.Row="1"
Name="documentListBox"
BorderThickness="1"
ItemsSource="{Binding}"
Visibility="{Binding ElementName=documentListBox,Path=HasItems, Converter={StaticResource boolToVisibilityConverter}}"
>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<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 Path=DeleteDocumentCommand}" HorizontalAlignment="Stretch" Content="Delete" />
<Button Command="{Binding Path=AddDocumentCommand}" HorizontalAlignment="Stretch" Content="Add" />
<Button Command="{Binding Path=OpenDocumentCommand}" HorizontalAlignment="Stretch" Content="Open" />
</StackPanel>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
ReportingViewModel(Controller):
public class ReportingViewModel : ViewModelBase
{
private ObservableCollection<MeetingViewModel> _meetingViewModelList;
public ReportingViewModel ()
{
}
public ObservableCollection<MeetingViewModel> MeetingViewModelList
{
get { return _meetingViewModelList; }
set
{
_meetingViewModelList= value;
this.RaisePropertyChanged("MeetingViewModelList");
}
}
}
MeetingViewModel:
public class MeetingViewModel: ViewModelBase
{
private ObservableCollection<DocumentViewModel> _documentViewModelList = new ObservableCollection<DocumentViewModel>();
private Meeting _meeting;
public MeetingViewModel(Meeting meeting)
{
_meeting= meeting;
_meeting.Documents.ForEach(doc => DocumentViewModelList.Add(new DocumentViewModel(doc)));
}
public ObservableCollection<DocumentViewModel> DocumentViewModelList
{
get { return _documentViewModelList; }
set
{
_documentViewModelList = value;
this.RaisePropertyChanged("DocumentViewModelList");
}
}
public string Content
{
get { return _meeting.Content; }
set
{
if (_meeting.Content == value)
return;
_meeting.Content = value;
this.RaisePropertyChanged("Content");
}
}
}
DocumentViewModel:
public class DocumentViewModel : ViewModelBase
{
private Document _document;
private RelayCommand _deleteDocumentCommand;
private RelayCommand _addDocumentCommand;
private RelayCommand _openDocumentCommand;
public DocumentViewModel(Document document)
{
_document = document;
}
private void DeleteDocument()
{
throw new NotImplementedException();
}
private bool CanDeleteDocument()
{
return _isSelected;
}
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())); }
}
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
if (_isSelected == value)
return;
_isSelected = value;
this.RaisePropertyChanged("IsSelected");
}
}
public string Name
{
get { return _document.DocumentName; }
set
{
if (_document.DocumentName == value)
return;
_document.DocumentName = value;
this.RaisePropertyChanged("Name");
}
}
}
推荐答案
我 问题是delete命令不知道选择已更改.
I think the problem is that delete command does not know that selection has changed.
将CanDeleteChanged添加到中继命令中,然后在this.RaisePropertyChanged("IsSelected")之后引发它.我以前在Prism应用中也遇到过类似的问题.
Add CanDeleteChanged to the relay command and raise it after this.RaisePropertyChanged("IsSelected"). I've had similar problems with Prism apps before.
编辑.实际上,您应该添加CanDeleteChanged并在其中放置一个断点,并查看是否在您期望它被调用时调用它.
EDIT. Infact you should add the CanDeleteChanged and put a breakpoint in it and see if its being called when you expect it to or not anyway.
对不起,我的意思是删除中继命令上的CanExecuteChanged事件.您的代码应在某处声明中继命令.为了提供信息,这里是
Sorry I meant CanExecuteChanged event on the Delete relay command. Your code should have the declaration of a relay command somewhere. For the sake of info here it is
公共类RelayCommand:ICommand{ #region字段
public class RelayCommand : ICommand{ #region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion // ICommand Members
}
这篇关于IsModel的IsSelected属性绑定到ListBox,只有第一项选择有效吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!