简体   繁体   中英

DataGrid on UserControl doesn't display binded ObservableCollection

I have a MainWindow with some buttons that loads a collection:

<Window x:Class="GUI.MainWindow.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:mainWindowViewModel="clr-namespace:GUI.MainWindow"
        xmlns:s="clr-namespace:Helpers"
        xmlns:configuration="clr-namespace:GUI.Configuration"
        xmlns:results="clr-namespace:GUI.Results"
        mc:Ignorable="d"
        Title="{Binding Path=Model.Title}"
        Width="Auto"
        WindowStartupLocation="CenterScreen">

    <Window.Resources>
        <DataTemplate DataType="{x:Type results:ResultViewModel}">
             <results:ResultView/>
        </DataTemplate>
    </Window.Resources>

    <!--DataContext-->
    <Window.DataContext>
        <mainWindowViewModel:MainWindowViewModel />
    </Window.DataContext>
    <!--DataContext-->

    <!--Main Grid-->
    <Grid Name="MainGrid"
          Margin="5"
          HorizontalAlignment="Stretch"
          VerticalAlignment="Stretch">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="8*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <!--Tabs-->
        <TabControl Grid.Row="1"
                    Grid.RowSpan="2"
                    Grid.Column="0"
                    VerticalAlignment="Stretch">

            <!--Result View-->
            <TabItem Header="{Binding Model.TabImportHeader}">
                <ContentControl Content="{Binding ResultViewModel}"/>
            </TabItem>
        </TabControl>
        <!--Tabs-->

        <!--Buttons-->
        <Grid Grid.Row="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Button Grid.Row="0"
                    Grid.Column="0"
                    Margin="10"
                    Height="25"
                    Width="150"
                    Content="Load"
                    Command="{Binding LoadCommand}" />
            <Button Grid.Row="0"
                    Grid.Column="2"
                    Margin="10"
                    Height="25"
                    Width="150"
                    Content="Reload"
                    Command="{Binding ReloadCommand}" />
        </Grid>
        <!--Buttons-->

    </Grid>
    <!--Main Grid-->
</Window>

Then I have a UserControl which should display the loaded collection, but shows nothing.

<UserControl x:Class="GUI.Results.ResultView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:GUI.Results"
             mc:Ignorable="d">

    <UserControl.DataContext>
        <local:ResultViewModel />
    </UserControl.DataContext>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="87*" />
            <ColumnDefinition Width="415*" />
            <ColumnDefinition Width="501*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <DataGrid Grid.Column="0"
                              Grid.ColumnSpan="3"
                              Grid.Row="0"
                              ItemsSource="{Binding Model.Collections}"
                              ColumnWidth="*"
                              AutoGenerateColumns="false"
                              HorizontalAlignment="Stretch"
                              IsReadOnly="True">
            <DataGrid.Resources>
                <Style TargetType="DataGridColumnHeader">
                    <Setter Property="HorizontalContentAlignment"
                                        Value="Center" />
                </Style>
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTextColumn Header="Filename"
                                                Binding="{Binding ResultInfo.Filename}"
                                                Width="Auto" />
                <DataGridTextColumn Header="Score 1"
                                                Binding="{Binding ResultInfo.Score1, StringFormat=F4, ConverterCulture=de-DE}"
                                                Width="Auto" />
                <DataGridTextColumn Header="Score 2"
                                                Binding="{Binding ResultInfo.Score2, StringFormat=F4, ConverterCulture=de-DE}"
                                                Width="Auto" />
                <DataGridTextColumn Header="Score 3"
                                                Binding="{Binding ResultInfo.Score3, StringFormat=F4, ConverterCulture=de-DE}"
                                                Width="Auto" />
                <DataGridTextColumn Header="Score 4"
                                                Binding="{Binding ResultInfo.Score4, StringFormat=F4, ConverterCulture=de-DE}"
                                                Width="Auto" />
                <DataGridTextColumn Header="SaMP"
                                                Binding="{Binding ResultInfo.SaMP}"
                                                Width="Auto" />
                <DataGridTextColumn Header="Spig"
                                                Binding="{Binding ResultInfo.Spig}"
                                                Width="Auto" />
                <DataGridTextColumn Header="Ppig"
                                                Binding="{Binding ResultInfo.Ppig, StringFormat=00.0##\\%}"
                                                Width="Auto" />
                <DataGridTextColumn Header="Pigment3"
                                                Binding="{Binding ResultInfo.Pigment3}"
                                                Width="Auto" />
                <DataGridTextColumn Header="Pigment4"
                                                Binding="{Binding ResultInfo.Pigment4}"
                                                Width="Auto" />
                <DataGridTextColumn Header="ZQ1"
                                                Binding="{Binding ResultInfo.ZQ1}"
                                                Width="Auto" />
                <DataGridTextColumn Header="ZQ2"
                                                Binding="{Binding ResultInfo.ZQ2}"
                                                Width="Auto" />
                <DataGridTextColumn Header="ZQ3"
                                                Binding="{Binding ResultInfo.ZQ3}"
                                                Width="Auto" />
                <DataGridTextColumn Header="ZQ4"
                                                Binding="{Binding ResultInfo.ZQ4}"
                                                Width="Auto" />
                <DataGridTextColumn Header="Message"
                                                Binding="{Binding ResultInfo.Message}"
                                                Width="Auto" />
                <DataGridTextColumn Header="Distance"
                                                Binding="{Binding ResultInfo.PowDistance, StringFormat=F2, ConverterCulture=de-DE}"
                                                Width="Auto" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</UserControl>

Here how I put the data inside the collection (values are there if I debug):

Application.Current.Dispatcher.Invoke(() => MainWindowViewModel.ResultViewModel.Model.Collections.Add(Collection));

Collections is type of ObservableCollection<>;

Seems that I'm missing something in the binding but I'm quite new to WPF and MVVM and I don't find it. I have read about DependencyProperty but I would like to have a ViewModel for my userControl as it will get eventually more complex.

I will really appreciate any help.

You have two instances of ResultViewModel , one in the MainWindowViewModel.ResultViewModel property, the other directly assigned to the UserControl's DataContext:

<UserControl.DataContext>
    <local:ResultViewModel />
</UserControl.DataContext>

Remove the above from the UserControl's XAML.

In general, a UserControl should never have its "own" view model, and you should never explicitly set its DataContext property in its XAML or code behind. Doing so overrides the value of the inherited DataContext, which contains the correct ResultViewModel instance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM