开发者

On Binding DataGrid in WPF. No Content is getting Visible. Only Rows are getting created

I binded my DataGrid in Wpf with a datatable. But no data is getting visible to me. I can see three rows being created in the grid in the UI but data is not getting visible. I tried to change forecolor and backcolor as well. I dont know why this is happening.

Any help will be appreciable.

My Code

Code Behind

I tried this way

  dt.AsEnumerable().ToList().ForEach(i => dgvSummary.Items.Add(i));

and also

dgvSummary.ItemsSource = dt.AsEnumerable().ToList();

XAML file

 <my:DataGrid xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit" 
              Name="dgvSummary" ItemsSource="{Binding}" Grid.Row="1" 
              MinWidth="520"    Height="180"            HorizontalAlignment="Left"
              FontSize="10"     Background="#FFFEEFC8" 
              AutoGenerateColumns="False"               SelectionUnit="Cell" 
              SelectionMode="Single"                  开发者_StackOverflow中文版  RowBackground="Transparent">
                    <my:DataGrid.Columns>                        
                        <my:DataGridTemplateColumn Header="First Name" 
                                                   IsReadOnly="True">
                            <my:DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Visibility="Visible"  
                                               Foreground="Red" 
                                               Background="Transparent" 
                                               Text="{Binding Path=First_Name}"/>
                                </DataTemplate>
                            </my:DataGridTemplateColumn.CellTemplate>
                        </my:DataGridTemplateColumn>
                        <my:DataGridTemplateColumn Header="Last Name" 
                                                   IsReadOnly="True">
                            <my:DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Foreground="Black" 
                                               Text="{Binding Path=LAST_NAME}"/>
                                </DataTemplate>
                            </my:DataGridTemplateColumn.CellTemplate>
                        </my:DataGridTemplateColumn>
                       </my:DataGrid.Columns>
                </my:DataGrid>


Try having a look at the output window during debugging - it will tell you if you have any binding errors.


I needed to solve this same issue and worked out examples where:

  1. The DataGrid is created in XAML
  2. The DataGrid is created in C# (code-behind)

For (1) I needed to set DataGrid.ItemsSource = "{Binding}" in XAML and then in C# to set DataGrid.DataContext to a DataSet

For (2) the approach of (1) didn't work. Instead I skipped setting a DataGrid.DataContext and set DataGrid.ItemsSource = DataTable.DefaultView. No DataSet was needed.

Here's a full working example of both:

MainWindow.xaml

<Window x:Class="DataGridTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="60" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0">
            <Button Content="Run1" Width="100" Click="RunGrid1_Click"></Button>
            <Button Content="Run2" Width="100" Click="RunGrid2_Click"></Button>
        </StackPanel>
        <ScrollViewer Name="sv1" Grid.Row="1">
            <DataGrid Name="dg1" ItemsSource="{Binding}"></DataGrid>
        </ScrollViewer>
    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Data;
using System.Management.Automation;
//C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll

namespace DataGridTest
{
    public partial class MainWindow : Window
    {
        string scriptText = @"$quotastat = @()
$quotastat += new-object psobject -property @{
    Identity = 1
    Value = '0.5GB'
    IssueWarningQuota = '471860 KB'
    ProhibitSendQuota = '498074 KB'
    ProhibitSendReceiveQuota = '524288 KB'
}
$quotastat += new-object psobject -property @{
    Identity = 2
    Value = '1GB (default)'
    IssueWarningQuota = '943719 KB'
    ProhibitSendQuota = '996148 KB'
    ProhibitSendReceiveQuota = '1048576 KB'
}
$quotastat";

        public MainWindow()
        {
            InitializeComponent();
        }

        private void RunGrid1_Click(object sender, RoutedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();

            PowerShell psExec = PowerShell.Create();
            psExec.AddScript(scriptText);

            Collection<PSObject> results;
            Collection<ErrorRecord> errors;
            results = psExec.Invoke();
            errors = psExec.Streams.Error.ReadAll();

            DataSet ds = new DataSet();
            DataTable dt = new DataTable();

            foreach (PSMemberInfo member in results[0].Members)
            {
                if (member.MemberType == PSMemberTypes.NoteProperty)
                {
                    dt.Columns.Add(member.Name, Type.GetType(member.TypeNameOfValue));
                }
            }

            foreach (PSObject result in results)
            {
                DataRow dr = dt.NewRow();

                foreach (PSPropertyInfo pi in result.Properties)
                {
                    dr[pi.Name] = pi.Value;
                }

                dt.Rows.Add(dr);
            }

            ds.Tables.Add(dt);
            dg1.DataContext = ds.Tables[0];
        }


        private void RunGrid2_Click(object sender, RoutedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();

            PowerShell psExec = PowerShell.Create();
            psExec.AddScript(scriptText);

            Collection<PSObject> results;
            Collection<ErrorRecord> errors;
            results = psExec.Invoke();
            errors = psExec.Streams.Error.ReadAll();

            DataGrid outputGrid = new DataGrid()
            {
                HorizontalAlignment = HorizontalAlignment.Stretch,
                VerticalAlignment = VerticalAlignment.Stretch,
                HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
            };

            DataTable dt = new DataTable();

            foreach (PSMemberInfo member in results[0].Members)
            {
                if (member.MemberType == PSMemberTypes.NoteProperty)
                {
                    dt.Columns.Add(member.Name, Type.GetType(member.TypeNameOfValue));
                }
            }

            foreach (PSObject result in results)
            {
                DataRow dr = dt.NewRow();

                foreach (PSPropertyInfo pi in result.Properties)
                {
                    dr[pi.Name] = pi.Value;
                }

                dt.Rows.Add(dr);
            }

            outputGrid.ItemsSource = dt.DefaultView;
            sv1.Content = outputGrid;
        }

    }
}


It doesn't work, because when you say

dgvSummary.ItemsSource = dt.AsEnumerable().ToList(); 

you are binding to IEnumerable<DataRow>. But DataRow doesn't have properties that you are trying to bind cells to, such as First_Name, Last_Name. You need to use indexer syntax to bind to DataRow fields, like this:

<TextBlock Visibility="Visible"                                                  Foreground="Red"                                                 Background="Transparent" Text="{Binding Path=[First_Name]}"/> 

The reason why it works for dt.DefaultView is because DataView implements IBindingListView and ITypedList, and DataGrid can interogate these interfaces and resolve property names when it's binding.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜