How do I use findcontrol in C#?

Hi,

I have the attached linqdatasource selecting event to populate my frontend asp.net listview...

How do I find a control within my listview's ItemTemplate within this event? My attempted code returns the error: "Object reference not set to an instance of an object" on code line 80? From the debugger I know that "query.UserId;" returns a value so it's my "ratingControl" reference that the debugger can't find?
protected void TrustsDataSource_Selecting(object sender, LinqDataSourceSelectEventArgs e)
    {

        TradeSelectorDataContext db = new TradeSelectorDataContext();

        var query =
                            (
                                from tt in db.tblTraders
                                join ttcl in db.tblCityLookups on tt.city_id equals ttcl.city_id
                                join lctt in db.tblCountryLookups on tt.country_id equals lctt.country_id
                                join tcl in db.tblCountyLookups on tt.county_id equals tcl.county_id
                                join twal in db.tblTraderWorkingAreaLookups on tt.trader_working_area_id equals twal.trader_working_area_id
                                join ttrade in db.tblTraderTrades on tt.UserId equals ttrade.UserId
                                join trade in db.tblTrades on ttrade.trade_id equals trade.trade_id
                                join ttt in db.tblTradeTradeTypes on trade.trade_id equals ttt.trade_id
                                join tradet in db.tblTradeTypes on ttrade.trade_type_id equals tradet.trade_type_id
                                join cj in db.tblCustomerJobs on trade.trade_id equals cj.trade_id
                                join tr in db.tblTraderRatings on tt.UserId equals tr.UserId
                                //join tc in db.tblCustomers on cj.UserId equals tc.UserId
                                orderby tt.trader_firstname ascending
                                select new
                                {
                                    tt.UserId
                                  ,
                                    tt.trader_title
                                  ,
                                    tt.trader_firstname
                                  ,
                                    tt.trader_surname
                                  ,
                                    tt.trader_phone1
                                  ,
                                    tt.trader_phone2
                                  ,
                                    tt.trader_working_area_id
                                  ,
                                    tt.trader_overall_rating
                                  ,
                                    trader_working_area_name = twal.trader_working_area_name.Substring(0, twal.trader_working_area_name.IndexOf('(')).Trim()
                                  ,
                                    trader_working_area_postcodes = twal.trader_working_area_name.Substring(twal.trader_working_area_name.IndexOf('(') + 1, twal.trader_working_area_name.LastIndexOf(')') - twal.trader_working_area_name.IndexOf('(') - 1).Trim()
                                  ,
                                    trade_type_name = tradet.trade_type_name == null ? "" : tradet.trade_type_name
                                  ,
                                    trade.trade_name
                                  ,
                                    ttrade.trade_type_id
                                  ,
                                    ttrade.trade_id
                                  ,
                                    tr.Rating01
                                  ,
                                    tr.Rating02
                                  ,
                                    tr.Rating03
                                  ,
                                    tr.Rating04
                                  ,
                                    tr.Rating05
                                }
                            ).Distinct().First();

            e.Result = query;

            if (query != null)
            {
                int[] rateValues;

                rateValues = new int[] 
                { 
                    query.Rating01
                    , query.Rating02
                    , query.Rating03
                    , query.Rating04
                    , query.Rating05 
                };

                Spaanjaars.Toolkit.ContentRating ratingControl = (Spaanjaars.Toolkit.ContentRating)lvTrustAccounts.FindControl("ContentRating1");

                ratingControl.ItemId = query.UserId;
                ratingControl.DataSource = rateValues;
                ratingControl.DataBind();
            }
        }

Open in new window

aspnet-scotlandAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

NazoUKCommented:
You'll need to use FindControl on the individual ListViewItem that your control resides in rather than the ListView itself.
If it's in a normal displayItem you can use lvTrustAccounts.Items[*index*].FindControl to access it. This would normally be done in some kind of row event handler, where you can get a reference to the item that raised the event.

If it's in an edit item you can use lvTrustAccounts.Items[lvTrustAccounts.EditIndex].FindControl or lvTrustAccounts.EditItem.FindControl - I recommend the 1st method as there is a bug that prevents the 2nd one working right unless you have SP1 installed.

If it's in the insertItem you can use lvTrustAccounts.InsertItem.FindControl

In all cases the ListView must have had it's data already bound to it to work, otherwise none of its items will have been created and you will always get null returned.
0
pschramaCommented:
It's not possible to access a control inside a ListView from within the datasource's selecting event, you can do that in the DataBound event of the ListView. You'll also need to check for the record that is being databound there.

(as explained in my response in http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/Q_25462265.html)

The query should be for all records though (without Distinct().First()), not a single distinct record, if you want the ListView to show all of them.
0
aspnet-scotlandAuthor Commented:
NazoUK,

Could you alter my code to show me what you mean?

I need to access my control from the datasource as that's where the query resides, or can I reference the query from another event?
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

aspnet-scotlandAuthor Commented:
pschrama,

How can I get my query results into the DataBound event of my listview as I need to set my control's properties on them...

ratingControl.ItemId = query.UserId;
ratingControl.DataSource = rateValues;
ratingControl.DataBind();

Thanks.
0
NazoUKCommented:
What exactly are you trying to achieve?

What is the LinqDataSource in question the DataSource for? The ListView itself or something else?

I'm confused why you are using a LinqDataSource at all if you are just going to use a manual query to produce the results.
0
aspnet-scotlandAuthor Commented:
I am using the linqdatasource to populate my listview control, this works great! The problem arose when I decided to place a rating control within my listview (http://imar.spaanjaars.com/QuickDocId.aspx?quickdoc=465) for each unique ID that was returned. Due to the way the rating control is configured (int array) I thought placing it's bound event within my datasources selecting event would work for each individual ID but it looks like I can't access controls within my listview through it's datasouce selecting event, how else can I populate my rating controls?
0
NazoUKCommented:
You should handle the ItemDataBound event of the ListView, rather than the DataSource event. Its EventArgs parameter e is of type ListViewItemEventArgs.

You should then cast the item property to type ListViewDataItem which allows you to get at the underlying data.

ListViewDataItem item = (ListViewDataItem)e.Item;

You can then find your rating control in the item like so:

Spaanjaars.Toolkit.ContentRating ratingControl = (Spaanjaars.Toolkit.ContentRating)item .FindControl("ContentRating1");

You can also access the individual dataitem that was bound to this row of the ListView, using item.DataItem if you cast this to whatever type your LinqDataSource is fetching you can find the unique id for the row and assign that against your rating control.
0
aspnet-scotlandAuthor Commented:
So my two events should be something like the attached...
protected void TrustsDataSource_Selecting(object sender, LinqDataSourceSelectEventArgs e)
    {

        TradeSelectorDataContext db = new TradeSelectorDataContext();
        
        var query =
                            (
                                from tt in db.tblTraders
                                join ttcl in db.tblCityLookups on tt.city_id equals ttcl.city_id
                                join lctt in db.tblCountryLookups on tt.country_id equals lctt.country_id
                                join tcl in db.tblCountyLookups on tt.county_id equals tcl.county_id
                                join twal in db.tblTraderWorkingAreaLookups on tt.trader_working_area_id equals twal.trader_working_area_id
                                join ttrade in db.tblTraderTrades on tt.UserId equals ttrade.UserId
                                join trade in db.tblTrades on ttrade.trade_id equals trade.trade_id
                                join ttt in db.tblTradeTradeTypes on trade.trade_id equals ttt.trade_id
                                join tradet in db.tblTradeTypes on ttrade.trade_type_id equals tradet.trade_type_id
                                join cj in db.tblCustomerJobs on trade.trade_id equals cj.trade_id
                                join tr in db.tblTraderRatings on tt.UserId equals tr.UserId
                                //join tc in db.tblCustomers on cj.UserId equals tc.UserId
                                orderby tt.trader_firstname ascending
                                select new
                                {
                                    tt.UserId
                                  ,
                                    tt.trader_title
                                  ,
                                    tt.trader_firstname
                                  ,
                                    tt.trader_surname
                                  ,
                                    tt.trader_phone1
                                  ,
                                    tt.trader_phone2
                                  ,
                                    tt.trader_working_area_id
                                  ,
                                    tt.trader_overall_rating
                                  ,
                                    trader_working_area_name = twal.trader_working_area_name.Substring(0, twal.trader_working_area_name.IndexOf('(')).Trim()
                                  ,
                                    trader_working_area_postcodes = twal.trader_working_area_name.Substring(twal.trader_working_area_name.IndexOf('(') + 1, twal.trader_working_area_name.LastIndexOf(')') - twal.trader_working_area_name.IndexOf('(') - 1).Trim()
                                  ,
                                    trade_type_name = tradet.trade_type_name == null ? "" : tradet.trade_type_name
                                  ,
                                    trade.trade_name
                                  ,
                                    ttrade.trade_type_id
                                  ,
                                    ttrade.trade_id
                                  ,
                                    tr.Rating01
                                  ,
                                    tr.Rating02
                                  ,
                                    tr.Rating03
                                  ,
                                    tr.Rating04
                                  ,
                                    tr.Rating05
                                }
                            ).Distinct().First();

            e.Result = query;

            if (query != null)
            {
                int[] rateValues;

                rateValues = new int[] 
                { 
                    query.Rating01
                    , query.Rating02
                    , query.Rating03
                    , query.Rating04
                    , query.Rating05 
                };
            }
}

//*********************************************************

protected void lvTrustAccounts_ItemDataBound(object sender, ListViewItemEventArgs e)
    {
        ListViewDataItem item = (ListViewDataItem)e.Item;

        Spaanjaars.Toolkit.ContentRating ratingControl = (Spaanjaars.Toolkit.ContentRating)item.FindControl("ContentRating1");

                ratingControl.ItemId = query.UserId;
                ratingControl.DataSource = rateValues;
                ratingControl.DataBind();
    }

Open in new window

0
NazoUKCommented:
The array for the ratings will need to be declared outside any methods so it is global scope.
Also you won't be able to access the query variable outside the event handler for the datasource so you should assign the userid to a global variable and then use that inside the ItemDataBound handler.

Otherwise it looks ok I guess, I've never used the rating control so couldn't tell you if that will work or not.
0
aspnet-scotlandAuthor Commented:
Could you alter my code to show me what you mean?

Thanks.
0
aspnet-scotlandAuthor Commented:
Maybe use something like the attached?....but how would I then get each userId from my query into this method?

Thanks.
private void BindData(Guid userId)
    {
        using (TradeSelectorDataContext db = new TradeSelectorDataContext())
        {
            int[] rateValues;

            // Get the item through LINQ. SingleOrDefault returns NULL when the item is not found.
            tblTraderRating result = (from tr in db.tblTraderRatings
                                      where tr.UserId == userId
                                      select tr).SingleOrDefault();

            if (result == null)
            {
                // Initialize to zero's
                rateValues = new int[] { 0, 0, 0, 0, 0 };
            }
            else
            {
                // Get the values from the result Rating instance.
                rateValues = new int[] 
            { 
                result.Rating01
                , result.Rating02
                , result.Rating03
                , result.Rating04
                , result.Rating05 
            };
            }

            Spaanjaars.Toolkit.ContentRating ratingControl = (Spaanjaars.Toolkit.ContentRating)lvTrustAccounts.FindControl("ContentRating1");

            ratingControl.ItemId = result.UserId;
            ratingControl.DataSource = rateValues;
            ratingControl.DataBind();
        }
    }

Open in new window

0
NazoUKCommented:
What do you mean each userId? Your query only appears to return one row.

But no, not like that. You've gone back to the original problem of using lvTrustAccounts.FindControl.
0
aspnet-scotlandAuthor Commented:
I want my query to return more than one row, so yes I will be removing the .First() reference. Ultimately my query should return multiple rows each with a rating control specific to the rows UserId value. I just don't understand how to make my array and my selecting events query for UserId global so other events can access them for reference?

Thanks.
0
pschramaCommented:
Alright, here's an attempt to put everything together. I'm assuming you will use your original query, which selects data from different tables and uses the anonymous type.

- First, create a method that does the query and databinding like you did above, and call it in the Page_PreInit event (this is where controls with a datasourceid call their databind method).

protected void Page_PreInit(object sender, EventArgs e)
{
   BindData();
}

private void BindData()
{
   TradeSelectorDataContext db = new TradeSelectorDataContext();

   var query =
      (
        from tt in db.tblTraders
        join ttcl in db.tblCityLookups on tt.city_id equals ttcl.city_id
        join lctt in db.tblCountryLookups on tt.country_id equals lctt.country_id
        join tcl in db.tblCountyLookups on tt.county_id equals tcl.county_id
        join twal in db.tblTraderWorkingAreaLookups on tt.trader_working_area_id equals twal.trader_working_area_id
        join ttrade in db.tblTraderTrades on tt.UserId equals ttrade.UserId
        join trade in db.tblTrades on ttrade.trade_id equals trade.trade_id
        join ttt in db.tblTradeTradeTypes on trade.trade_id equals ttt.trade_id
        join tradet in db.tblTradeTypes on ttrade.trade_type_id equals tradet.trade_type_id
        join cj in db.tblCustomerJobs on trade.trade_id equals cj.trade_id
        join tr in db.tblTraderRatings on tt.UserId equals tr.UserId
        //join tc in db.tblCustomers on cj.UserId equals tc.UserId
        orderby tt.trader_firstname ascending
        select new
        {
            tt.UserId
          ,
            tt.trader_title
          ,
            tt.trader_firstname
          ,
            tt.trader_surname
          ,
            tt.trader_phone1
          ,
            tt.trader_phone2
          ,
            tt.trader_working_area_id
          ,
            tt.trader_overall_rating
          ,
            trader_working_area_name = twal.trader_working_area_name.Substring(0, twal.trader_working_area_name.IndexOf('(')).Trim()
          ,
            trader_working_area_postcodes = twal.trader_working_area_name.Substring(twal.trader_working_area_name.IndexOf('(') + 1, twal.trader_working_area_name.LastIndexOf(')') - twal.trader_working_area_name.IndexOf('(') - 1).Trim()
          ,
            trade_type_name = tradet.trade_type_name == null ? "" : tradet.trade_type_name
          ,
            trade.trade_name
          ,
            ttrade.trade_type_id
          ,
            ttrade.trade_id
          ,
            tr.Rating01
          ,
            tr.Rating02
          ,
            tr.Rating03
          ,
            tr.Rating04
          ,
            tr.Rating05
        }
      );

   lvTrustAccounts.DataSource = query;
   lvTrustAccounts.DataBind();
}

- Then, add a DataBound event to the listview. Within there you can both access the dataitem and use reflection to get the data you need, as well as the rating control to set the necessary properties. I'm assuming all rating values are ints and can't be null. It's very important that the types are correct and the spelling of the property names in the GetProperty call are correct too.

protected void lvTrustAccounts_ItemDataBound(object sender, ListViewItemEventArgs e)
{
   Object dataRecord = ((ListViewDataItem)e.Item).DataItem; // Get the dataitem and place it into dataRecord
   Type anonType = dataRecord.GetType(); // get the anonymous type
   
   // Get user id and rating values using reflection
   int userid = (int)anonType.GetProperty("UserId").GetValue(dataRecord, null);
   int rating1 = (int)anonType.GetProperty("Rating01").GetValue(dataRecord, null);
   int rating2 = (int)anonType.GetProperty("Rating02").GetValue(dataRecord, null);
   int rating3 = (int)anonType.GetProperty("Rating03").GetValue(dataRecord, null);
   int rating4 = (int)anonType.GetProperty("Rating04").GetValue(dataRecord, null);
   int rating5 = (int)anonType.GetProperty("Rating05").GetValue(dataRecord, null);

   // Put rating values in array
   int[] rateValues = new int[] { rating1, rating2, rating3, rating4, rating 5 };

   // Get a reference to the rating control, and set+bind the data
   Spaanjaars.Toolkit.ContentRating ratingControl = (Spaanjaars.Toolkit.ContentRating)e.Item.FindControl("ContentRating1");
   
   ratingControl.ItemId = userid;
   ratingControl.DataSource = rateValues;
   ratingControl.DataBind();            
}

Perhaps I'll have time tomorrow to confirm the reflection code with a little test of my own. I'm just going by online references at the moment, can't actually try it out right now.
0
pschramaCommented:
Slight amendment to my post, I accidentily mentioned the wrong event to do the databind. It should be Page_PreRender. Fixed version of that section below:

- First, create a method that does the query and databinding like you did above, and call it in the Page_PreRender event (just before this, is where controls with a datasourceid call their databind method).

protected void Page_PreRender(object sender, EventArgs e)
{
   BindData();
}
0
NazoUKCommented:
Actually it might be possible to simplify the problem and do this declaratively if the rating control supports it.

in your markup tag for the rating try adding:

ItemId='<%#Eval("userid")%>' DataSource='<%#GetRatingArray((int)Eval("rating1"),(int)Eval("rating2"),(int)Eval("rating3"),(int)Eval("rating4"),(int)Eval("rating5"))%>'

Then in your codebehind:

protected IList<int> GetRatingArray(int rating1, int rating2, int rating3, int rating4, int rating5)
{
     return new int[] {rating1, rating2, rating3, rating4,rating5};
}

You'll need a using System.Collections.Generic at the top if you don't already have one.
0
aspnet-scotlandAuthor Commented:
NazoUK,

I get the error: "System.MethodAccessException: System.Collections.Generic.List`1..ctor()"?

Thanks.
0
NazoUKCommented:
Does it say where the error is?

Also make sure you've put IList<int> not List<int>
0
aspnet-scotlandAuthor Commented:
pschrama,

Thanks for your code but do I keep my listview's current linqdatasource (attached) or remove it? I'm guessing the OnPreRender event is called from my listview?

Thanks.
<asp:LinqDataSource 
                                            ID="TrustsDataSource" 
                                            runat="server" 
                                            ContextTypeName="TradeSelectorDataContext"
                                            TableName="tblCustomers" />
                                        <asp:ListView 
                                            ID="lvTrustAccounts" 
                                            runat="server"
                                            DataKeyNames="UserId"
                                            DataMember="DefaultView" 
                                            OnItemDataBound="lvTrustAccounts_ItemDataBound"
                                            OnPreRender="Page_PreRender">

Open in new window

0
pschramaCommented:
If you do the querying and databinding in your code (e.g. called in Page_PreRender as in my example) then you don't need the LinqDataSource. But you can also keep the LinqDataSource and let that take care of querying and databinding, if you prefer.
0
aspnet-scotlandAuthor Commented:
NazoUK,

No line number is declared. I have attached the stack trace if that helps and I definitely have IList<int> declared.

Thanks.
[MethodAccessException: System.Collections.Generic.List`1..ctor()]
   T_632a8dd7_bbc7_4874_8e47_730a9444e1d5.CreateInstance() +0
   System.Web.HttpRuntime.FastCreatePublicInstance(Type type) +419
   System.Web.UI.WebControls.LinqDataSourceView.AsQueryable(Object o) +446
   System.Web.UI.WebControls.LinqDataSourceView.ExecuteSelectQuery(LinqDataSourceSelectEventArgs selectEventArgs, Object selectResult, Object table, Boolean storeOriginalValues) +327
   System.Web.UI.WebControls.LinqDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments) +457
   System.Web.UI.DataSourceView.Select(DataSourceSelectArguments arguments, DataSourceViewSelectCallback callback) +19
   System.Web.UI.WebControls.DataBoundControl.PerformSelect() +142
   System.Web.UI.WebControls.ListView.PerformSelect() +57
   System.Web.UI.WebControls.BaseDataBoundControl.DataBind() +73
   System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound() +82
   System.Web.UI.WebControls.ListView.CreateChildControls() +55
   System.Web.UI.Control.EnsureChildControls() +87
   System.Web.UI.Control.PreRenderRecursiveInternal() +44
   System.Web.UI.Control.PreRenderRecursiveInternal() +171
   System.Web.UI.Control.PreRenderRecursiveInternal() +171
   System.Web.UI.Control.PreRenderRecursiveInternal() +171
   System.Web.UI.Control.PreRenderRecursiveInternal() +171
   System.Web.UI.Control.PreRenderRecursiveInternal() +171
   System.Web.UI.Control.PreRenderRecursiveInternal() +171
   System.Web.UI.Control.PreRenderRecursiveInternal() +171
   System.Web.UI.Control.PreRenderRecursiveInternal() +171
   System.Web.UI.Control.PreRenderRecursiveInternal() +171
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +842

Open in new window

0
aspnet-scotlandAuthor Commented:
pschrama,

I would like to keep my LinqDataSource in that case as I am performing runtime inserts and updates through it.

Unfortunately I am receiving the error: "Can't bind a datasource without a valid ItemId" on line "lvTrustAccounts.DataBind();" within my BindData method of the attached code?

Thanks.
protected void Page_PreRender(object sender, EventArgs e)
    {
        BindData();
    }

    private void BindData()
    {
        TradeSelectorDataContext db = new TradeSelectorDataContext();

        var query =
           (
             from tt in db.tblTraders
             join ttcl in db.tblCityLookups on tt.city_id equals ttcl.city_id
             join lctt in db.tblCountryLookups on tt.country_id equals lctt.country_id
             join tcl in db.tblCountyLookups on tt.county_id equals tcl.county_id
             join twal in db.tblTraderWorkingAreaLookups on tt.trader_working_area_id equals twal.trader_working_area_id
             join ttrade in db.tblTraderTrades on tt.UserId equals ttrade.UserId
             join trade in db.tblTrades on ttrade.trade_id equals trade.trade_id
             join ttt in db.tblTradeTradeTypes on trade.trade_id equals ttt.trade_id
             join tradet in db.tblTradeTypes on ttrade.trade_type_id equals tradet.trade_type_id
             join cj in db.tblCustomerJobs on trade.trade_id equals cj.trade_id
             join tr in db.tblTraderRatings on tt.UserId equals tr.UserId
             //join tc in db.tblCustomers on cj.UserId equals tc.UserId
             orderby tt.trader_firstname ascending
             select new
             {
                 tt.UserId
               ,
                 tt.trader_title
               ,
                 tt.trader_firstname
               ,
                 tt.trader_surname
               ,
                 tt.trader_phone1
               ,
                 tt.trader_phone2
               ,
                 tt.trader_working_area_id
               ,
                 tt.trader_overall_rating
               ,
                 trader_working_area_name = twal.trader_working_area_name.Substring(0, twal.trader_working_area_name.IndexOf('(')).Trim()
               ,
                 trader_working_area_postcodes = twal.trader_working_area_name.Substring(twal.trader_working_area_name.IndexOf('(') + 1, twal.trader_working_area_name.LastIndexOf(')') - twal.trader_working_area_name.IndexOf('(') - 1).Trim()
               ,
                 trade_type_name = tradet.trade_type_name == null ? "" : tradet.trade_type_name
               ,
                 trade.trade_name
               ,
                 ttrade.trade_type_id
               ,
                 ttrade.trade_id
               ,
                 tr.Rating01
               ,
                 tr.Rating02
               ,
                 tr.Rating03
               ,
                 tr.Rating04
               ,
                 tr.Rating05
             }
           );

        lvTrustAccounts.DataSource = query;
        lvTrustAccounts.DataBind();
    }

    protected void lvTrustAccounts_ItemDataBound(object sender, ListViewItemEventArgs e)
    {
        Object dataRecord = ((ListViewDataItem)e.Item).DataItem; // Get the dataitem and place it into dataRecord
        Type anonType = dataRecord.GetType(); // get the anonymous type

        // Get user id and rating values using reflection
        Guid userid = (Guid)anonType.GetProperty("UserId").GetValue(dataRecord, null);
        int rating1 = (int)anonType.GetProperty("Rating01").GetValue(dataRecord, null);
        int rating2 = (int)anonType.GetProperty("Rating02").GetValue(dataRecord, null);
        int rating3 = (int)anonType.GetProperty("Rating03").GetValue(dataRecord, null);
        int rating4 = (int)anonType.GetProperty("Rating04").GetValue(dataRecord, null);
        int rating5 = (int)anonType.GetProperty("Rating05").GetValue(dataRecord, null);

        // Put rating values in array
        int[] rateValues = new int[] 
        { 
            rating1, rating2, rating3, rating4, rating5 
        };

        // Get a reference to the rating control, and set and bind the data
        Spaanjaars.Toolkit.ContentRating ratingControl = (Spaanjaars.Toolkit.ContentRating)e.Item.FindControl("ContentRating1");

        ratingControl.ItemId = userid;
        ratingControl.DataSource = rateValues;
        ratingControl.DataBind();
    }

Open in new window

0
aspnet-scotlandAuthor Commented:
and pschrama my linqdatasource and listview now look like the attached....
<asp:LinqDataSource 
                                            ID="TrustsDataSource" 
                                            runat="server" 
                                            ContextTypeName="TradeSelectorDataContext"
                                            TableName="tblCustomers" />
                                        <asp:ListView 
                                            ID="lvTrustAccounts" 
                                            runat="server"
                                            DataKeyNames="UserId"
                                            DataMember="DefaultView" 
                                            OnItemDataBound="lvTrustAccounts_ItemDataBound"
                                            OnPreRender="Page_PreRender">

Open in new window

0
NazoUKCommented:
Do you only get that error when you add the changes I suggested? The error trace seems to indicate it is related to something else.
To implement this change go back to the code you had in your original question and remove this:

if (query != null)
            {
                int[] rateValues;

                rateValues = new int[]
                {
                    query.Rating01
                    , query.Rating02
                    , query.Rating03
                    , query.Rating04
                    , query.Rating05
                };

                Spaanjaars.Toolkit.ContentRating ratingControl = (Spaanjaars.Toolkit.ContentRating)lvTrustAccounts.FindControl("ContentRating1");

                ratingControl.ItemId = query.UserId;
                ratingControl.DataSource = rateValues;
                ratingControl.DataBind();
            }
0
aspnet-scotlandAuthor Commented:
NazoUK,

I had already removed the above code you referred to. The two main events of interest in my code behind look like the attached....

Thanks.
protected void TrustsDataSource_Selecting(object sender, LinqDataSourceSelectEventArgs e)
    {

        TradeSelectorDataContext db = new TradeSelectorDataContext();

        var query =
                            (
                                from tt in db.tblTraders
                                join ttcl in db.tblCityLookups on tt.city_id equals ttcl.city_id
                                join lctt in db.tblCountryLookups on tt.country_id equals lctt.country_id
                                join tcl in db.tblCountyLookups on tt.county_id equals tcl.county_id
                                join twal in db.tblTraderWorkingAreaLookups on tt.trader_working_area_id equals twal.trader_working_area_id
                                join ttrade in db.tblTraderTrades on tt.UserId equals ttrade.UserId
                                join trade in db.tblTrades on ttrade.trade_id equals trade.trade_id
                                join ttt in db.tblTradeTradeTypes on trade.trade_id equals ttt.trade_id
                                join tradet in db.tblTradeTypes on ttrade.trade_type_id equals tradet.trade_type_id
                                join cj in db.tblCustomerJobs on trade.trade_id equals cj.trade_id
                                join tr in db.tblTraderRatings on tt.UserId equals tr.UserId
                                //join tc in db.tblCustomers on cj.UserId equals tc.UserId
                                orderby tt.trader_firstname ascending
                                select new
                                {
                                    tt.UserId
                                  ,
                                    tt.trader_title
                                  ,
                                    tt.trader_firstname
                                  ,
                                    tt.trader_surname
                                  ,
                                    tt.trader_phone1
                                  ,
                                    tt.trader_phone2
                                  ,
                                    tt.trader_working_area_id
                                  ,
                                    tt.trader_overall_rating
                                  ,
                                    trader_working_area_name = twal.trader_working_area_name.Substring(0, twal.trader_working_area_name.IndexOf('(')).Trim()
                                  ,
                                    trader_working_area_postcodes = twal.trader_working_area_name.Substring(twal.trader_working_area_name.IndexOf('(') + 1, twal.trader_working_area_name.LastIndexOf(')') - twal.trader_working_area_name.IndexOf('(') - 1).Trim()
                                  ,
                                    trade_type_name = tradet.trade_type_name == null ? "" : tradet.trade_type_name
                                  ,
                                    trade.trade_name
                                  ,
                                    ttrade.trade_type_id
                                  ,
                                    ttrade.trade_id
                                  ,
                                    tr.Rating01
                                  ,
                                    tr.Rating02
                                  ,
                                    tr.Rating03
                                  ,
                                    tr.Rating04
                                  ,
                                    tr.Rating05
                                }
                            ).Distinct().First();

            e.Result = query;
    }

    protected IList<int> GetRatingArray(int Rating01, int Rating02, int Rating03, int Rating04, int Rating05)
    {
        return new int[] 
        { 
            Rating01, Rating02, Rating03, Rating04, Rating05 
        };
    }

Open in new window

0
aspnet-scotlandAuthor Commented:
and NazoUK my rating control looks like the attached...
<isp:ContentRating 
                                                            ID="ContentRating1" 
                                                            runat='server'
                                                            LegendText="rates: {0} avg: {1}" 
                                                            ItemId='<%# Eval("UserId") %>' 
                                                            DataSource='<%#GetRatingArray((int)Eval("Rating01"),(int)Eval("Rating02"),(int)Eval("Rating03"),(int)Eval("Rating04"),(int)Eval("Rating05"))%>' />

Open in new window

0
aspnet-scotlandAuthor Commented:
pschrama,

The error I'm receiving actually comes from my ContentRating Contol, but I'm not too sure why it's getting flagged on the line I specified within my BindData method? Shouldn't it get flagged within my ItemDataBound event?

Thanks.
0
aspnet-scotlandAuthor Commented:
NazoUK,

I didn't get that error before your changes either.

Thanks.
0
pschramaCommented:
You can remove the attribute OnPreRender="Page_PreRender" because this will be called by the page already, so no need to call it again in the control's prerender event.

I'm getting a bit confused by the different approaches, but just to be clear: the query and databinding should only occur in one place, or some unexpected things could occur. You can do it either in the selecting event of the datasource like you did before, in a seperate method which is called by the page, or define it in the linqdatasource. So if you have the query in different places right now, I would remove the duplicates.

And yes, I would have expected that error in the itemdatabound event too. I did notice you changed the type for userid to Guid. Is that the type used by the linq class? Perhaps you can check what value it is getting before it is assigned to the rating control in the itemdatabound event, and see if any problem occurs there.

Or now that I think about it, when you call databind the error might be caused by the eval statement in the control: ItemId='<%#Eval("userid")%>'.

It would probably be best to work on each approach separately, since now they're getting intertwined and possibly conflicting with each other. Better to make a copy of your page and try out the different approaches in each page. If you do this, make sure to change the class name of the copy, and the Inherits attribute of the copied page (at the top of the markup).
0
aspnet-scotlandAuthor Commented:
pschrama,

Sorry about the confussion but I am working on both approaches seperately as you suggested, I don't think it would be possible to combine the two of them. Anyway, for your approach I don't have the eval statement referred within my control so that covers that. I have also removed the OnPreRender reference but I still get the same error? The query and the binding for the listview are happening in the same place, it's only the binding for my rating control that is happening in a different place (ItemDataBound event).

Thanks.
0
pschramaCommented:
Thanks for clearing that up, at least I'm sure there's no impact from the other approach then.

Is the ItemDataBound event getting fired at all? Or does the exception occur before it even goes there?
I'll have another look later, got some work to do at the moment.
0
aspnet-scotlandAuthor Commented:
pschrama,

I don't think my ItemDataBound event is able to find the  "UserId" values coming out of your BindData method to fill the rating control.....

ratingControl.ItemId = result.UserId;

Can I make the selected UserId values a global array some how and then use it within this event?

Thanks.

P.S. UserId is of type Guid or uniqueidentifier
0
aspnet-scotlandAuthor Commented:
pschrama,

I placed a breakpoint on the ItemDataBound event and my code does not get stepped into, therefore the error is occuring before this event is fired.

Thanks.
0
pschramaCommented:
Not sure what the problem is, but perhaps you can try taking out the "Guid userid = " code, and adding "ItemId='<%#Eval("userid")%>'" to the ItemTemplate.

Another thing to try would be to totally remove the LinqDataSource, just to see if it has any adverse effect on the databinding (I have the feeling that databinding for select is still done through the LinqDataSource as well).

If neither of those have any effect, please attach all the relevant code and page markup (including itemtemplate) and I'll have another look.
0
aspnet-scotlandAuthor Commented:
None of your suggestions seem to work :(

Basically our BindData method requires an ItemId (UserId value) before the listview databind call...

lvTrustAccounts.DataBind();

The query within the BindData supplies this UserId value but I don't know how to map it against my ratingControl's ItemId? ....so frustrating.

Can I zip my .sln file to you, is that possible?

Thanks.


0
pschramaCommented:
For some reason the rating control is causing problems, that's all I can say at this point. According to http://imar.spaanjaars.com/QuickDocId.aspx?quickdoc=410, the exception "Can't bind a datasource without a valid ItemId" is thrown inside the rating control's DataBind() method.

But according to you, the ItemDataBound method doesn't even get called, which means the rating DataBind shouldn't get called either, which doesn't make sense. You could try to set a default value for ItemId in the markup (ItemId="1") just to see if there are no errors that way.

I guess I'll need to see the whole thing and try it out for myself to get this sorted. I don't know when I'll be able to try it out properly though, I don't have access to Visual Studio at home until my pc is back from repairs. As an alternative, try posting on http://imar.spaanjaars.com/QuickDocId.aspx?quickdoc=410 and see if the creator can shed some light on this?
0
aspnet-scotlandAuthor Commented:
pschrama,

You're right, once I comment out the ContentRating control within the ItemTemplate of my frontend listview control my debug steps into the ItemDataBound event. This is strange as at this point I'm not binding any data to the control - weird! I'll try to contact the creator, thanks.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.