Model的IsSelected属性绑定到ListBox

Model的IsSelected属性绑定到ListBox

本文介绍了IsModel的IsSelected属性绑定到ListBox,只有第一项选择有效吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个绑定到 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,只有第一项选择有效吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 21:42