为什么我的ObservableCollection <string>绑定到Listbox不起作用?</string>

时间:2014-12-26 16:54:51

标签: c# wpf mvvm listbox mvvm-light

当我更新ObservableCollection<string>并以某种方式调用RaisePropertyChanged(..)时,其内容未显示在我在WPF中的Listbox中。我不知道我做错了什么。

关键部分是我更新FileNames属性的地方:

public class HistoricalDataViewRawDataViewModel : ViewModelBase
{
    private string _currentDirectory;
    private ObservableCollection<string> _fileNames;
    private List<string> _rawData;

    public ICommand ChangeDirectoryCommand { get; private set; }
    public string CurrentDirectory
    {
        get { return _currentDirectory; }
        set
        {
            if (_currentDirectory != value)
            {
                _currentDirectory = value;
                RaisePropertyChanged("CurrentDirectory");
            }
        }
    }
    public ObservableCollection<string> FileNames
    {
        get { return _fileNames; }
        set
        {
            if (_fileNames != value)
            {
                _fileNames = value;
                RaisePropertyChanged("FileNames");
            }
        }
    }

    public List<string> RawData
    {
        get { return _rawData; }
        set
        {
            if (_rawData != value)
            {
                _rawData = value;
                RaisePropertyChanged("RawData");
            }
        }
    }

    public HistoricalDataViewRawDataViewModel()
    {
        ChangeDirectoryCommand = new RelayCommand(ChangeDirectory);
        var fileDirectory = Properties.Settings.Default.HistoricalData_RawDataSourceDirectory;

        //set current directory
        CurrentDirectory = fileDirectory;

        //load all fileNames
        LoadAvailableFileNames(fileDirectory);
    }

    private void ChangeDirectory()
    {
        using (var folderDialog = new FolderBrowserDialog())
        {
            folderDialog.SelectedPath = CurrentDirectory;
            folderDialog.ShowDialog();

            //set current directory
            CurrentDirectory = folderDialog.SelectedPath;

            //save current directory to settings
            Properties.Settings.Default.HistoricalData_RawDataSourceDirectory = CurrentDirectory;
            Properties.Settings.Default.Save();

            //load files in chosen directory
            LoadAvailableFileNames(CurrentDirectory);
        }
    }

    private void LoadAvailableFileNames(string directory)
    {
        FileNames = new ObservableCollection<string>(FileIO.GetFileNamesInDirectory(directory, false, true));
    }
    private async void LoadRawData(string fileName)
    {

    }}

这是xaml代码。它应该按原样工作,因为我希望显示ObservableCollection<string>。我从代码隐藏中向列表框添加了几个项目,它显示得很好:

DataContext="{Binding HistoricalDataViewRawDataViewModel, Source={StaticResource Locator}}">

<Grid>

    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition />
    </Grid.RowDefinitions>

    <StackPanel Grid.Row="0" Orientation="Horizontal">
        <ToggleButton Margin="10"  HorizontalAlignment="Left" VerticalAlignment="Center" Content="Choose Directory" FontSize="18" Foreground="White" Command="{Binding ChangeDirectoryCommand}"/>
        <TextBlock 
            Margin="10"
            FontSize="18"
            Foreground="White"
            HorizontalAlignment="Stretch"
            VerticalAlignment="Stretch"
            TextAlignment="Center"
            Text="{Binding CurrentDirectory}"/>
    </StackPanel>

    <dxdo:DockLayoutManager Grid.Row="1">

        <dxdo:LayoutGroup Orientation="Vertical">

            <dxdo:LayoutPanel ItemHeight="7*">
                <dxdo:LayoutControlItem>
                    <ListBox Name="MyListBox" ItemsSource="{Binding FileNames}"/>
                </dxdo:LayoutControlItem>
            </dxdo:LayoutPanel>

            <dxdo:LayoutPanel Caption="Activity Log" ItemHeight="200" >
                <dxdo:LayoutControlItem>
                    <ListBox/>
                </dxdo:LayoutControlItem>
            </dxdo:LayoutPanel>

        </dxdo:LayoutGroup>

    </dxdo:DockLayoutManager>

</Grid>

2 个答案:

答案 0 :(得分:2)

根据DevExpress中的this support ticket,只需移除LayoutControlItem即可。

我使用您的XAML和一些虚拟数据创建了一个示例项目,它工作正常:

<Window x:Class="WpfApplication12.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
        Title="MainWindow" Height="350" Width="525">
    <dxdo:DockLayoutManager Grid.Row="1">

        <dxdo:LayoutGroup Orientation="Vertical">

            <dxdo:LayoutPanel ItemHeight="7*">
                <!-- notice the removal of LayoutControlItem here -->
                <ListBox ItemsSource="{Binding FileNames}"/>
            </dxdo:LayoutPanel>

            <dxdo:LayoutPanel Caption="Activity Log" ItemHeight="200" >
                <ListBox/>
            </dxdo:LayoutPanel>
        </dxdo:LayoutGroup>
    </dxdo:DockLayoutManager>
</Window>

代码背后:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        //Dummy data
        DataContext = new
        {
            FileNames = Enumerable.Range(0, 5).Select(x => "File" + x.ToString())
        };
    }
}

结果:

enter image description here

答案 1 :(得分:1)

我认为这些dxdo控件是非标准控件?我假设这些控件破坏了继承机制。继承机制适用于所有FrameworkElement对象。这意味着属性值沿逻辑树继承。这使您可以在外部Grid上设置datacontext属性,但在TextBlock上使用它。您在Grid上设置的值由StackPanel继承,然后由TextBlock再次继承。这仅适用于从FrameworkElement继承的对象。

您可以直接在ListBox上设置datacontext吗? 。如果这样做,那么这表明传感上下文已被破坏。