WPF按钮位于datacontext之外,无法绑定

时间:2010-09-11 18:54:02

标签: wpf binding controls datacontext

alt text您好

我的 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())); }
        }

1 个答案:

答案 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媒体资源发布的代码看起来不错。看起来问题出在其他地方。