سؤال

تحديث

أقوم بشكل أساسي بربط الاستعلام بـ WinForms DataGridView.أريد أن تكون رؤوس الأعمدة مناسبة وأن تحتوي على مسافات عند الحاجة.على سبيل المثال، أريد أن يكون رأس العمود First Name بدلاً من FirstName.


كيف يمكنك إنشاء أسماء الأعمدة المخصصة الخاصة بك في LINQ؟

على سبيل المثال:

Dim query = From u In db.Users _
            Select u.FirstName AS 'First Name'
هل كانت مفيدة؟

المحلول 3

لقد قمت بحل مشكلتي بنفسي ولكن جميع إجاباتك كانت مفيدة للغاية ووجهتني في الاتجاه الصحيح.

في LINQ الاستعلام، إذا كان اسم العمود يحتوي على أكثر من كلمة واحدة، فسأفصل الكلمات بشرطة سفلية:

Dim query = From u In Users _
            Select First_Name = u.FirstName

ثم داخل Paint طريقة DataGridView, ، لقد استبدلت جميع الشرطات السفلية داخل الرأس بمسافة:

Private Sub DataGridView1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles DataGridView1.Paint
    For Each c As DataGridViewColumn In DataGridView1.Columns
        c.HeaderText = c.HeaderText.Replace("_", " ")
    Next
End Sub

نصائح أخرى

كما ينص CQ، لا يمكن أن يكون لديك مسافة لاسم الحقل، ولكن يمكنك إرجاع أعمدة جديدة.

var query = from u in db.Users
            select new
            {
                FirstName = u.FirstName,
                LastName = u.LastName,
                FullName = u.FirstName + " " + u.LastName
            };

ثم يمكنك ربط الاستعلام المتغير من الأعلى أو تكراره مهما كان....

foreach (var u in query)
{
   // Full name will be available now 
   Debug.Print(u.FullName); 
}

إذا أردت إعادة تسمية الأعمدة، يمكنك ذلك، ولكن لن يُسمح بالمسافات.

var query = from u in db.Users
            select new
            {
                First = u.FirstName,
                Last = u.LastName
            };

سيتم إعادة تسمية الاسم الأول إلى الأول واسم العائلة إلى الأخير.

إذا كنت تريد تغيير نص الرأس، فيمكنك ضبط ذلك في تعريف GridView...

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">
    <Columns>
        <asp:BoundField DataField="FirstName" HeaderText="First Name" />
    </Columns>
</asp:GridView>

في الكود الموجود خلفك، يمكنك ربط المستخدمين وسيقوم بتعيين الرأس على الاسم الأول.

protected void Page_Load(object sender, EventArgs e)
{
     // initialize db datacontext
     var query = from u in db.Users
                 select u;
     GridView1.DataSource = query;
     GridView1.DataBind();
}

يمكنك أيضًا إضافة معالج حدث ليحل محل تلك الشرطات السفلية لك!

لأولئك منكم الذين يحبون C #:

datagrid1.ItemDataBound += 
    new DataGridItemEventHandler(datagrid1_HeaderItemDataBound);

ويجب أن يبدو المعالج الخاص بك هكذا:

private void datagrid1_HeaderItemDataBound(object sender, DataGridItemEventArgs e)
{

    if (e.Item.ItemType == ListItemType.Header)
    {
        foreach(TableCell cell in e.Item.Cells)
            cell.Text = cell.Text.Replace('_', ' ');
    }

}

سأستخدم:

var query = from u in db.Users
            select new
            {
                FirstName = u.FirstName,
                LastName = u.LastName,
                FullName = u.FirstName + " " + u.LastName
            };

(من سكوت نيكولز)

إلى جانب وظيفة تقرأ سلسلة Camel Case وتدرج مسافات قبل كل حرف كبير جديد (يمكنك إضافة قواعد للمعرف وما إلى ذلك).ليس لدي رمز لهذه الوظيفة معي حاليًا، ولكن كتابته بسيطة إلى حد ما.

يمكنك جعل نتائجك تحتوي على شرطات سفلية في اسم العمود واستخدام HeaderTemplate في TemplateField لاستبدال الشرطة السفلية بمسافات.أو فئة فرعية من DataControlField لـ GridView وتجاوز خاصية HeaderText:

namespace MyControls 
{
public SpacedHeaderTextField : System.Web.UI.WebControls.BoundField
 { public override string HeaderText
    { get 
       { string value = base.HeaderText;
         return (value.Length > 0) ? value : DataField.Replace(" ","");
       }
      set
       { base.HeaderText = value;
       }     
    }
 } 
 }

أس بي إكس:

<%@Register TagPrefix="my" Namespace="MyControls" %>

<asp:GridView DataSourceID="LinqDataSource1" runat='server'>
  <Columns>
     <my:SpacedHeaderTextField DataField="First_Name" />
  </Columns>
</asp:GridView>

لا أفهم لماذا يتعين عليك القيام بذلك، إذا كنت تحاول القيام بذلك لشبكة أو شيء من هذا القبيل، فلماذا لا تقوم فقط بتسمية الرأس في HTML؟

ما ستفعله في الواقع هو تعيين مرجع متغير للإرجاع، ولا توجد طريقة لتسمية متغير بمسافة.هل هناك نتيجة نهائية وراء قيامك بذلك، ربما إذا عرفنا الهدف النهائي يمكننا مساعدتك في التوصل إلى حل مناسب.

استخدام طريقة ملحق Linq:

SomeDataSource.Select(i => new { NewColumnName = i.OldColumnName, NewColumnTwoName = i.OldColumnTwoName});

كما أشار الآخرون بالفعل، إذا كان عنوان الرأس وما إلى ذلك معروفًا في وقت التصميم، فقم بإيقاف تشغيل AutoGeneratedColumns وقم فقط بتعيين العنوان وما إلى ذلك في تعريف الحقل بدلاً من استخدام الأعمدة التي تم إنشاؤها تلقائيًا.من المثال الخاص بك، يبدو أن الاستعلام ثابت وأن العناوين معروفة في وقت التصميم، لذا ربما يكون هذا هو خيارك الأفضل.

ومع ذلك [، على الرغم من أن سؤالك لا يحدد هذا المطلب] - لو نص الرأس (والتنسيق وما إلى ذلك) هو لا معروف في وقت التصميم ولكن سيتم تحديده في وقت التشغيل ، وإذا كنت بحاجة إلى إنشاء أعمدة (باستخدام AutogenerateColumns = صحيح ") هناك حلول لذلك.

إحدى الطرق للقيام بذلك هي إنشاء فئة تحكم جديدة ترث عرض الشبكة.يمكنك بعد ذلك تعيين الرأس والتنسيق وما إلى ذلك للحقول التي تم إنشاؤها تلقائيًا عن طريق تجاوز "CreateAutoGeneratedColumn" الخاص بعرض الشبكة.مثال:

//gridview with more formatting options
namespace GridViewCF
{
    [ToolboxData("<{0}:GridViewCF runat=server></{0}:GridViewCF>")]
    public class GridViewCF : GridView
    {
        //public Dictionary<string, UserReportField> _fieldProperties = null;

        public GridViewCF()
        {
        }

        public List<FieldProperties> FieldProperties
        {
            get
            {
                return (List<FieldProperties>)ViewState["FieldProperties"];
            }
            set
            {
                ViewState["FieldProperties"] = value;
            }
        }

        protected override AutoGeneratedField CreateAutoGeneratedColumn(AutoGeneratedFieldProperties fieldProperties)
        {
            AutoGeneratedField field = base.CreateAutoGeneratedColumn(fieldProperties);
            StateBag sb = (StateBag)field.GetType()
                .InvokeMember("ViewState",
                BindingFlags.GetProperty |
                BindingFlags.NonPublic |
                BindingFlags.Instance,
                null, field, new object[] {});

            if (FieldProperties != null)
            {
                FieldProperties fps = FieldProperties.Where(fp => fp.Name == fieldProperties.Name).Single();
                if (fps.FormatString != null && fps.FormatString != "")
                {
                    //formatting
                    sb["DataFormatString"] = "{0:" + fps.FormatString + "}";
                    field.HtmlEncode = false;
                }

                //header caption
                field.HeaderText = fps.HeaderText;

                //alignment
                field.ItemStyle.HorizontalAlign = fps.HorizontalAlign;
            }

            return field;
       }
    }

    [Serializable()]
    public class FieldProperties
    {
        public FieldProperties()
        { }

        public FieldProperties(string name, string formatString, string headerText, HorizontalAlign horizontalAlign)
        {
            Name = name;
            FormatString = formatString;
            HeaderText = headerText;
            HorizontalAlign = horizontalAlign;
        }

        public string Name { get; set; }
        public string FormatString { get; set; }
        public string HeaderText { get; set; }
        public HorizontalAlign HorizontalAlign { get; set; }
    }
}

أعتقد أنه يمكن تحقيق ذلك باستخدام نوع الاسم الصريح

 system.Name,
 sysentity.Name 
 //change this to 
 entity = sysentity.Name

يمكنك استخدام الكلمة الأساسية "Let":

Dim query = From u In db.Users _
            let First_Name = u.FirstName
            Select First_Name

كما أظهرت الإجابات الأخرى هنا، فإن هذا ليس مفيدًا.ومع ذلك، فإن الكلمة الأساسية Let مفيدة لإجراء استعلامات أكثر تعقيدًا (هذا المثال ليس في أعلى رأسي ولا يتطلب الكلمة الأساسية Let للعمل):

from x in dc.Users 
let match = regex.Match(".*ass.*", x.Name) 
let comment = match ? "*snicker*" : "sup"
select new { Name = x.Name, Comment = comment };

تم ضبط جهاز VS2008 الخاص بي الآن، لذا لا يمكنني التحقق.في C#، يمكنك استخدام "= - ماذا عن

Dim query = From u In db.Users _
            Select 'First Name' = u.FirstName
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top