5

Alright so this is going to be hard to explain.

Scenario:

I have a DataGrid defined as follows:

<DataGrid Height="100" Name="test" IsReadOnly="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="URL"></DataGridTextColumn>
        <DataGridTextColumn Header="PORT"></DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

data grid visual

It has two headers and I need to add data, I've done a lot of research that suggests using an ObservableCollection since that will fire the DataChanged event.

I can formulate this data with long boring code that probably isn't relevant (you'll see why below).

Problem:

The 200 rows are added but the text itself isn't in the table

blank rows

Troubleshooting:

I turned on debugging and with screenshots help, you can see there is actual data but it won't insert it into the rows, but it adds the rows.

Data Collection

Relevant Code:

ObservableCollection<Proxy> collection = new ObservableCollection<Proxy>();
collection = GetData(ips,ports);
test.CanUserAddRows = true;
test.ItemsSource = null;
test.ItemsSource = collection;
MessageBox.Show("Done");

NOTE: I added the .ItemSource = null; and then set it equal to the collection as that enabled the rows to show up. I've tried using the suggested: test.DataContext = collection; But, no rows get added at all, and yes just as this test the data is visible in debug mode as being part of the context/itemsource.

UPDATE:

I've tried implementing the following XAML with the same results

<DataGrid Height="100" Name="test" IsReadOnly="False" ItemsSource="{Binding collection}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="URL" Binding="{Binding ip}"></DataGridTextColumn>
        <DataGridTextColumn Header="PORT" Binding="{Binding port}"></DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

Proxy Class:

public class Proxy
{
    public string ip;
    public string port;
}

UPDATE 2: When adding get and set methods the following was my result:

four columns?

5
  • Where do you tell your app what do write into the columns? You just set the itemssource (what you should do in xaml if you ask me) Commented Feb 25, 2015 at 5:42
  • Hi, can you explain a little more please? Do you mean to create DataBindings in XAML? Commented Feb 25, 2015 at 5:44
  • You have no binding in your DataGridTextColumn and hence they don't show any data. Commented Feb 25, 2015 at 5:45
  • @PhilipStuyck, if I have a ObservableCollection, how would I bind to this or do I have to split it? Commented Feb 25, 2015 at 5:49
  • There is already 2 answers overlapping mostly. You have to bind to your Proxy members. You can also experiment with AutogenerateColumns = true. just to be sure there is data. Commented Feb 25, 2015 at 5:53

3 Answers 3

14

You are missing to define the Properties for the bindings: at least, change the Proxy class like this:

public class Proxy
{
    public string ip {get; set;}
    public string port {get; set;}
}
Sign up to request clarification or add additional context in comments.

8 Comments

Wow that is very interesting. See my updated question, that kind of worked.
Maybe you can delete the autogenerate columns if you have the explicit bindings
Bingo, had to force it to be false.
Actually this is just the beginning because you need to implement INotifyPropertyChanged on the Proxy class. user3596113's answer is more complete and should work.
If the only changes of those properties are from that datagrid you don't need to notify. That is incomplete if you have to reflect updates from other sources than the data grid itself.
|
2

You have no binding for your columns. This is an example on how to do it :

<DataGrid x:Name="RelatieSearchGrid" AutoGenerateColumns="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
                       ItemsSource="{Binding Relaties.View}" IsReadOnly="True"   
                       SelectionMode="Single">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Naam" Binding="{Binding Naam}"/>
            <DataGridTextColumn Header="Straat" Binding="{Binding Straat}"/>
            <DataGridTextColumn Header="Postcode" Binding="{Binding Postcode}"/>
            <DataGridTextColumn Header="Gemeente" Binding="{Binding Gemeente}"/>
            <DataGridTextColumn Header="BTW" Binding="{Binding BTW}"/>
        </DataGrid.Columns>
    </DataGrid>

In your case since the collection contains proxy, you need to bind to the proxy members. You didn't show the proxy code so I can only guess what those members are. If you want to go via the datacontext, then you need to work with a viewmodel. In that case I suggest you read something about MVVM first.

4 Comments

Hi, I think I started to implement what you're suggesting here, check my updated question. Or I may be completely off base here
Your binding has to contain the exact member names to proxy ie ip and port and not Url and Port. Binding is case sensitive!!
Sorry, I've updated the question and updated my xaml with sadly no change.
try this first AutoGenerateColumns="True"
1

You should first set the ItemsSource in xaml:

<DataGrid ItemsSource="{Binding test}" ... >

Then you should add your TemplateColumns like this:

<DataGrid ItemsSource="{Binding test}" ...>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Url}"
                                            Header="URL" />
        <DataGridTextColumn Binding="{Binding Port}"
                                            Header="Port" />
    </DataGrid.Columns>
</DataGrid>

Note that this will need your Objects stored in the ObservableCollection test to have an Url and a Port Porperty.

Change your Model class to implement INPC and adjust your properties like this:

public class Proxy : INPC
{
    public String Url
    {
        get
        {
            return url;
        }
        set
        {
            if (url== value) {
                return;
            }
            url= value;
            RaisePropertyChanged("Url");
        }
    }
    private string url;

    public String Port
    {
        get
        {
            return port;
        }
        set
        {
            if (port== value) {
                return;
            }
            port= value;
            RaisePropertyChanged("Port");
        }
    }
    private string port;
}

8 Comments

Hi, ok I gave that a shot and it didn't produce a different result, check my updated questionl.
Did you read my last sentence? Do you have any binding errors in your output window at runtime?
System.Windows.Data Error: 40 : BindingExpression path error: 'ip' property not found on 'object' ''Proxy' (HashCode=6855507)'. BindingExpression:Path=ip; DataItem='Proxy' (HashCode=6855507); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'port' property not found on 'object' ''Proxy Yes I do
Show the model class which is stored in your ObservableCollection please.
Either you need to rename your properties to Url and Port. Or you need to change your xaml code. Also your model class should implement INPC. Maybe you should read a little bit about WPF and MVVM first.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.