ตั้งค่าหลายปุ่มเนื้อหาในวง for (each)

แก้ไข: แก้ไขแล้ว

ฉันพบวิธีแก้ปัญหาของฉันแล้ว:

        for (int i = 0; i < SPItems.Count; i++)
        {
            SubItem1txt.Text = SPItems[i]; i++;
            SubItem2txt.Text = SPItems[i]; i++;
            SubItem3txt.Text = SPItems[i]; i++;
            SubItem4txt.Text = SPItems[i]; i++;
            SubItem5txt.Text = SPItems[i]; i++;
            SubItem6txt.Text = SPItems[i]; i++;
            SubItem7txt.Text = SPItems[i]; i++;
            SubItem8txt.Text = SPItems[i]; i++;
        }

เพื่อให้สิ่งต่าง ๆ ชัดเจน ฉันใช้แบบสอบถามเช่น: SELECT * FROM table LIMIT 8 เพื่อเติม List<string> SPItems = new List<string>(); ของฉัน ซึ่งหมายความว่ารายการของฉันมีค่า 8 ค่าหรือน้อยกว่าเสมอ

แน่นอนว่าใน for loop ของฉัน ลูปจะพยายามเติมให้ครบ 8 ปุ่ม

แต่ ถ้าจำนวนค่า ในรายการของฉัน น้อยกว่าสมมติว่า... 5 หรือ 6 มันจะส่ง ArgumentOutOfRangeException : Index was out of range

ฉันจะแก้ไขปัญหานี้ได้อย่างไร?


ฉันมีรายการ List<string> SPItems = new List<string>(); ซึ่งมีข้อมูลที่ดึงมาจากฐานข้อมูล

ฉันต้องการวนซ้ำรายการ และสำหรับแต่ละรายการใน SPItems ฉันต้องการตั้งค่า button's content ที่แตกต่างกัน

สมมติว่ารายการของฉันประกอบด้วย:

  • ค่า1
  • ค่า2
  • ค่า3

สิ่งที่ฉันต้องการตอนนี้คือ:

  • Button1.Content = value1;
  • Button2.Content = value2;
  • Button3.Content = value3;

person DeMama    schedule 14.03.2013    source แหล่งที่มา
comment
แล้วการวางปุ่มของคุณในรายการหรืออาร์เรย์แทนที่จะตั้งชื่อคล้ายกันล่ะ? นี่คือจุดประสงค์ของอาร์เรย์   -  person Benjamin Gruenbaum    schedule 15.03.2013
comment
ทำไมไม่ผูก SPItems กับ ItemsControl ที่เต็มไปด้วย Buttons ล่ะ?   -  person sa_ddam213    schedule 15.03.2013
comment
กระบวนการเริ่มต้นนี้มีค่าสูงสุด 8 ค่า (8 ปุ่ม) หากกดปุ่มอื่นอีก 8 ค่าถัดไปจะถูกดึงมาจากฐานข้อมูลของฉัน...   -  person DeMama    schedule 15.03.2013
comment
ดูเหมือนจะมีความเข้าใจผิดบางอย่าง ฉันคิดว่า.. ฉันมีปุ่มของฉันแล้ว ฉันแค่ต้องตั้งค่าเนื้อหาจากรายการ Button1.Content = "my value1"; Button2.Content = "my value 2"; ฯลฯ...   -  person DeMama    schedule 15.03.2013


คำตอบ (4)


หากปุ่มของคุณชื่อเหมือน Button1, Button2, Button3 ....

คุณสามารถใช้ FindChild<T>()
ที่นี่คุณจะได้รับวิธีการ

for(int i =0; i< SPItems.Count;i++) // iterates for each item in your SPItems
{
     Button foundButton =  UIHelper.FindChild<Button>(Application.Current.MainWindow, "Button"+i);

     if(foundButton != null) //Protecteted agains trying to use Null-Reference
     {
          var foundButtonTextBlock =foundButton .Content as TextBlock

          if(foundButtonTextBlock != null)//Protecteted agains trying to add Text by Null-Reference
               foundButtonTextBlock.Text  = SPItems[i];
     }
}

แก้ไข

ตามปกติ:

 for(int i =0; i< SPItems.Count;i++) // iterates for each item in your SPItems
    {
         TextBlock foundTextBlock =  UIHelper.FindChild<TextBlock>(this, "SubItem"+1+i+"txt");

         if(foundTextBlock != null) //Protecteted agains trying to add Text by Null-Reference
         {
              foundTextBlock .Text  = SPItems[i];
         }
    }

เป็นวิธีที่เจ็บปวด:

int i =0;
if(SPItems.Count >0)
{
    SubItem1txt.Text = SPItems[i]; 
    i++;
}
if(SPItems.Count >1)
{
    SubItem2txt.Text = SPItems[i];
    i++;
}
if(SPItems.Count >2)
{
    SubItem3txt.Text = SPItems[i];
    i++;
}
if(SPItems.Count >3)
{
    SubItem4txt.Text = SPItems[i]; 
    i++;
}
if(SPItems.Count >4)
{
    SubItem5txt.Text = SPItems[i]; 
    i++;
}
if(SPItems.Count >0)
{
    SubItem6txt.Text = SPItems[i];
    i++;
}
if(SPItems.Count >5)
{
    SubItem7txt.Text = SPItems[i];
    i++;
}
if(SPItems.Count >6)
{
    SubItem8txt.Text = SPItems[i];
    i++;
}
//..... never ever do this
person WiiMaxx    schedule 15.03.2013
comment
หากฉันมีตัวแทนมากกว่านี้ ฉันจะให้ +1 แก่คุณ เพราะคำตอบนี้ช่วยฉันได้มากที่สุด ฉันจำเป็นต้องใช้สิ่งนี้ใน for loop: SubItem1txt.Text = SPItems[i]; i++; และ SubItem2txt.Text = SPItems[i]; i++; ของฉัน ฯลฯ แน่นอนว่าฉันมีปุ่มให้กรอก 8 ปุ่ม.. ตอนนี้ถ้า SPItems.Count มีดัชนีน้อยกว่า 8 ข้อยกเว้นจะเกิดขึ้น ฉันสามารถพูด if (SPItems.Count == 1) =>> fill 1 button หรือ if (SPItems.Count == 2) =>> fill 2 buttons ได้ไหม ขอบคุณนะ!! - person DeMama; 15.03.2013
comment
@DeMama คุณยกเว้นอะไร? เพราะถ้าคุณเพิ่งคัดลอกมันไปและแทนที่ TextBlock ด้วย Button ปัญหาเดียวที่อาจเกิดขึ้นได้ถ้าคุณมี 7 ปุ่มและ SPItems.Count>7 คุณจะได้รับ NullReferencExeptoin เพราะไม่ได้ตรวจสอบว่า foundButton != null - person WiiMaxx; 15.03.2013
comment
ฉันพบวิธีแก้ปัญหาแล้ว ขอบคุณสำหรับความช่วยเหลือของคุณ ฉันโพสต์คำตอบแล้ว :) ไชโย ! - person DeMama; 15.03.2013

ห้ามจัดการองค์ประกอบ UI ในโค้ดสำหรับงานง่ายๆ เหล่านี้ นี่คือวิธี WPF ในการทำสิ่งที่คุณถาม:

<Window x:Class="WpfApplication4.Window18"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window18" Height="300" Width="300">
    <ItemsControl ItemsSource="{Binding}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button Content="{Binding}" Margin="2"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

รหัสเบื้องหลัง:

using System.Windows;
using System.Linq;

namespace WpfApplication4
{
    public partial class Window18 : Window
    {
        public Window18()
        {
            InitializeComponent();

            DataContext = Enumerable.Range(0, 20).Select(x => "Item" + x);
        }
    }
}

นี่คือลักษณะที่ปรากฏในหน้าจอของฉัน:

ป้อนคำอธิบายรูปภาพที่นี่

person Federico Berasategui    schedule 14.03.2013
comment
อืม โอเค.. แต่ฉันมีปุ่มอยู่แล้ว.. ฉันแค่ต้องการตั้งค่า content หรือ text inside those buttons - person DeMama; 15.03.2013
comment
@DeMama จากนั้นสร้าง ViewModel ที่เหมาะสมเพื่อเก็บค่า string ของคุณและผูกคุณสมบัติ Buttons Content <Button Content="{Binding SomeStringInTheViewModel}"/> - person Federico Berasategui; 15.03.2013

นี่เป็นวิธีแก้ปัญหาที่สกปรก แต่ถ้าคุณจะจัดการปุ่มทั้งหมดในแบบฟอร์มมันก็คุ้มค่า วิธีที่ง่ายที่สุดที่ฉันรู้คือการเพิ่มปุ่มทั้งหมดลงใน ArrayList (ใช่ ด้วยตนเอง นั่นเป็นส่วนที่เจ็บปวด) จากนั้นก็แค่วนซ้ำรายการนั้น

person evanmcdonnal    schedule 14.03.2013
comment
หรือ List<Button> แทนที่จะเป็น ArrayList - person Mohammad Dehghan; 15.03.2013
comment
@ MD.Unicorn ใช่แล้ว เดิมทีฉันเพิ่งพูดว่า 'รายการ' แต่ ArrayList มีประสิทธิภาพที่ดีกว่ามาก ดังนั้นฉันจึงตัดสินใจระบุโดยเฉพาะ แน่นอนว่ามีโครงสร้างข้อมูลบางอย่างที่จะทำงานได้ดีที่นี่ - person evanmcdonnal; 15.03.2013

ขอบคุณ WiiMaxx ฉันพบวิธีแก้ปัญหาแล้ว!

ด้วยการใช้วิธีนี้ ฉันตั้งค่าข้อความปุ่มด้วยข้อมูลที่ดึงมาจากฐานข้อมูลของฉันได้สำเร็จ

มันกลายเป็น foreach ลูป แต่ตอนนี้มันทำงานได้ตรงตามที่ต้องการแล้ว แก้ไข: พบเวอร์ชัน for

ฉันมี WrapPanel ซึ่งมี buttons ของฉัน ซึ่งมี TextBlock's ของฉันอีกครั้ง

เนื่องจาก TextBlock's ของฉันไม่ได้ขึ้นต้นด้วย 0 แต่ด้วย 1 (เช่น SubItem1txt) ฉันจึงต้องสร้าง int เพิ่มเติม ฉันหวังว่านี่จะเป็นประโยชน์สำหรับใครบางคน

ขอบคุณทุกคน :) !

เวอร์ชัน foreach:

int i = 1;
int a = 0;
foreach (string spi in SPItems)
    {
        WrapPanel pnl = UIHelper.FindChild<WrapPanel>(this, "SubItems");
        Button btn = UIHelper.FindChild<Button>(pnl, "SubItem" + i);
        TextBlock tb = UIHelper.FindChild<TextBlock>(btn, "SubItem" + i + "txt");
        btn.Visibility = Visibility.Visible;
        tb.Text = SPItems[a];
        a++;
        i++;
    }

สำหรับเวอร์ชัน:

    int i = 1;
    for (int a = 0; a < SPItems.Count; a++)
    {
        WrapPanel pnl = UIHelper.FindChild<WrapPanel>(this, "SubItems");
        Button btn = UIHelper.FindChild<Button>(pnl, "SubItem" + i);
        TextBlock tb = UIHelper.FindChild<TextBlock>(btn, "SubItem" + i + "txt");
        btn.Visibility = Visibility.Visible;
        tb.Text = SPItems[a];
        i++;
    }
person DeMama    schedule 15.03.2013