Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 如果ViewModel的IsSelected属性绑定到ListBox,则仅第一项选择有效?_Wpf_Listbox_Viewmodel_Selected - Fatal编程技术网

Wpf 如果ViewModel的IsSelected属性绑定到ListBox,则仅第一项选择有效?

Wpf 如果ViewModel的IsSelected属性绑定到ListBox,则仅第一项选择有效?,wpf,listbox,viewmodel,selected,Wpf,Listbox,Viewmodel,Selected,我有一个会议视图模型列表绑定到数据网格。 每个会议视图模型都有一个文档视图模型列表绑定到DataGrid的DataGridTemplate列中的列表框 DocumentViewModel的IsSelected属性绑定到ListBox的Item属性IsSelected 我在输出控制台中没有发现绑定错误 DocumentViewModel中的“删除文档”按钮将检查其CanExecute方法: private bool CanDeleteDocument() {

我有一个会议视图模型列表绑定到数据网格。 每个会议视图模型都有一个文档视图模型列表绑定到DataGrid的DataGridTemplate列中的列表框

DocumentViewModel的IsSelected属性绑定到ListBox的Item属性IsSelected

我在输出控制台中没有发现绑定错误

DocumentViewModel中的“删除文档”按钮将检查其CanExecute方法:

private bool CanDeleteDocument()
        {
            return _isSelected;
        }
当我在列表框中选择第一个
项目时,删除按钮被启用。 当我在列表框中选择第二、第三等项目时,删除按钮始终处于禁用状态

我尝试只粘贴重要的代码,并剪切其他内容:

我刚刚尝试用一个列表框(不是DataGrid的一部分)重建场景,我得到了相同的行为:/

我很乐意听到任何提示:)

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>

我确信它可以这样工作,但是用另一种方式跟踪所选项目不是更容易吗?例如,绑定到包装实际集合的ICollectionView(例如ListCollectionView)允许使用内置的选择跟踪机制(ICollectionView的CurrentItem)。或者,您可以使用列表框的SelectedValue和SelectedValuePath。

我认为问题在于delete命令不知道选择已更改

将CanDeleteChanged添加到中继命令中,并在此之后将其提升。提升属性更改(“IsSelected”)。我以前在Prism应用程序中也遇到过类似的问题

编辑。事实上,您应该添加CanDeleteChanged并在其中放置一个断点,然后查看它是否在您期望的时候被调用

抱歉,我的意思是删除中继命令上的CanExecuteChanged事件。您的代码应该在某个地方声明了中继命令。为了信息起见,这里是

公共类中继命令:ICommand { #区域字段

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
只读操作\u执行;
只读谓词_canExecute;
#endregion//字段
#区域构造函数
公共中继命令(操作执行)
:此(执行,空)
{
}
公共RelayCommand(操作执行,谓词canExecute)
{
if(execute==null)
抛出新的ArgumentNullException(“执行”);
_执行=执行;
_canExecute=canExecute;
}
#endregion//构造函数
#区域ICommand成员
[调试步骤至]
公共布尔CanExecute(对象参数)
{
返回_canExecute==null?true:_canExecute(参数);
}
公共事件事件处理程序CanExecuteChanged
{
添加{CommandManager.RequerySuggested+=value;}
删除{CommandManager.RequerySuggested-=value;}
}
public void Execute(对象参数)
{
_执行(参数);
}
#endregion//ICommand成员

}

Hm。。。并不是说我现在想放弃这个想法,而是你说Alex是对的。我非常专注于使用ViewModel选择ISS。我现在做了如下操作:SelectedItem=“{Binding SelectedDocumentViewModel,Mode=TwoWay}”并且在DocumentViewModel:private bool CanDeleteDocument(){if(SelectedDocumentViewModel!=null)返回true;else返回false;}有效,但是我想知道为什么IsSelected不起作用!;-)我猜这是因为ListBoxItem的IsSelected属性是由ListBox在内部操纵的,这会干扰绑定,但我可能会偏离这一点。不太确定。对不起。。。但是如何将属性添加到RelayCommand?请给我一个代码片段,我不知道代码应该是什么样子。另一个问题是,尽管documentListBox是空的,但按钮已启用。。。我认为这个问题是由于删除按钮位于DocumentViewModel中。由于没有currentMeeting.DocumentList.Count>0,我可以绑定到,因为在加载整个会议时,我必须启用/禁用Delete按钮。我应该将删除按钮和其他按钮移动到控制器上,对吗?但即使这样,我在控制器上也只有一个按钮命令,但在视图中,我有10个会议,每个会议都有一个删除文档按钮。不工作…似乎我必须将按钮放在DocumentListViewModel中,就像它们在WAF for wpf中那样!?好的,我现在制作了DocumentListViewModel,它是一个多么痛苦的绑定尝试和错误。但现在我都在工作了!删除按钮被禁用如果文档列表是空的或者没有选择任何文档,我应该开始一个博客:PSorry最近几天都没有选中。对于CanDeleteChanged,您应该查看RelayCommand的构造函数参数。
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");
        }


   }     
    }
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");
        }
    }       
}
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