Кнопки WPF находятся вне текста данных и не могут быть связаны - PullRequest
1 голос
/ 11 сентября 2010

alt text Здравствуйте,

У меня есть 3 кнопки: добавить, удалить, открыть как RelayCommands в моем DocumentViewModel .Ниже вы видите, как я их связал.Конечно, эти привязки не работают, потому что для данных установлено значение ItemsSource из ListBox , а кнопки находятся вне этого ...

Тогда я попытался установить DataContext для первой StackPanel, которую вы видите в моем фрагменте кода.

следующим образом: <StackPanel DataContext="{Binding DocumentViewModelList}" >

НО, тогда возникла новая проблема ...теперь документы больше не отображаются / не перечислены в ListBox: /

Как заставить ОБА работать?

<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, захватив DocumentViewModelList через привязку RelativeSource с FindAncestor.Я попробовал кое-что, но не повезло, может быть, кто-то может опубликовать хороший фрагмент:)

ОК Я нашел решение: <ListBox ItemsSource="{Binding}" ...

это привязка к текущему DataContext, который является "DocumentViewModelList"круто!

ОБНОВЛЕНИЕ 2:

хорошо, есть еще одна проблема, может быть, если кто-то может предоставить решение по этому вопросу, я помечаю эту тему как решение тогда.Не хотите открывать новую тему, потому что весь текст + фрагмент кода один и тот же ... Теперь проблема в том, что>> Выбор 1-го документа активирует кнопку.Выбор любой другой кнопки не активирует кнопку, ПОЧЕМУ?Что не так с привязкой моего свойства 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())); }
        }

1 Ответ

2 голосов
/ 11 сентября 2010

Является ли DocumentViewModelList собственностью вашего DocumentViewModel?

Как правило, у меня есть ViewModel для этого окна, которое отображает ObservableCollection<T>, где T - это то, что вы хотите отобразить в списке. Затем вы можете назначить DataContext Window / Page / и т. Д. ViewModel, а затем привязать ItemsSource ListBox к этому свойству ObservableCollection<T>.

Например, здесь будет фрагмент моей ViewModel.

public class SomeViewModel
{
  public ObservableCollection<SingleDocumentViewModel> Docs {get; private set; }

  // other properties can go here
}

В коде для XAML (я обычно делаю это в конструкторе), вы можете установить DataContext для нового экземпляра вашей ViewModel

public AwesomeDocumentList()
{
  this.DataContext = new SomeViewModel();
  // the rest of the constructor
}

С установленным в DataContext окном вы можете привязать ItemsSource к раскрытому свойству (я назвал его Docs)

<ListBox ItemsSource="{Binding Docs}" ... />

Надеюсь, это поможет.

Обновление

В RelayCommand для кнопки есть ли что-то, указанное для предиката CanExecute? Если нет, то я считаю, что RelayCommand по умолчанию всегда включен. Но если у вас есть предикат, посмотрите там.

Код, который вы разместили для свойства IsSelected, выглядит хорошо. Похоже, проблема в другом.

...