สร้าง StackPanels แบบไดนามิกและอ้างอิงถึงสิ่งใดๆ ในโค้ดด้านหลัง

ในรูปแบบที่ง่ายที่สุด...

ฉันต้องการสร้าง StackPanels ได้มากเท่าที่ต้องการ จากนั้นจึงเพิ่มสี่เหลี่ยมผืนผ้าลงไป จากนั้นเพื่อให้สามารถเปลี่ยนสีเติมของสี่เหลี่ยมอันใดอันหนึ่งได้เมื่อฉันคลิกปุ่มเริ่มเป็นต้น ทั้งหมดในโค้ดเบื้องหลัง

ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชม

ตัวอย่างเช่น หากเบียร์ที่เราชื่นชอบเป็นผู้เขียนกรอบงาน ฉันสามารถทำได้ดังนี้:

เอ็กซ์เอเอ็มแอล:

<Page
    x:Class="Test2.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Test2"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal">
            <Button Name="StartButton" Content="Start" Click="StartButton_Click" Height="30" Width="200" Margin="5"/>
        </StackPanel>

        <StackPanel Grid.Row="1" Name="myStackPanel" VerticalAlignment="Top"/>

    </Grid>
</Page>

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

namespace Test2
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();

            for (var i = 0; i < 5; i++) // The 5 here could be any number
            {
                myStackPanel.Children.Add(new StackPanel
                {
                    Name = "myPanel" + i,
                    Orientation = Orientation.Horizontal
                });

                for (var j = 0; j < 10; j++) // The 10 here could be any number
                {
                    ("myPanel" + i).Children.Add(new Rectangle
                    {
                        Name = "myRectangle" + i + "-" + j,
                        Fill = new SolidColorBrush(Colors.Black),
                        Width = 20,
                        Height = 20,
                        Margin = new Thickness(1)
                    });
                }
            }
        }

        private void StartButton_Click(object sender, RoutedEventArgs e)
        {
            // E.G. To change the Fill color of Rectangle4 in StackPanel2

            ("myRectangle" + 2 + "-" + 4).Fill = new SolidColorBrush(Colors.Red);
        }
    }
}

person gaw    schedule 19.12.2015    source แหล่งที่มา
comment
สิ่งนี้ควรแนะนำคุณ stackoverflow.com/questions/874380/ .. คุณเพียงแค่ต้องแก้ไขมันในลักษณะที่คุณมีคุณสมบัติชื่อในการเพิ่มและแก้ไขคุณสมบัติ และแน่นอน คุณควรใช้ VisualTreeHelper   -  person tgpdyk    schedule 19.12.2015
comment
โอเค ขอบคุณ @tgpdyk ฉันจะลองดู   -  person gaw    schedule 19.12.2015
comment
@tgpdyk ฉันดูเหมือนจะได้รับข้อผิดพลาดในการลองสิ่งใดสิ่งหนึ่ง: อาร์กิวเมนต์ 1: ไม่สามารถแปลงจาก 'Windows.UI.Composition.Visual' เป็น 'Windows.UI.Xaml.DependencyObject' - ฉันมักจะพบสิ่งนี้เมื่ออ้างถึงเอกสารอื่น คุณ (หรือใครก็ตาม) ช่วยระบุให้เจาะจงกว่านี้ได้ไหม - สามเณรที่นี่ : (   -  person gaw    schedule 19.12.2015
comment
@gaw ขออภัย ฉันไม่รู้ว่ามันเป็น uwp ฉันไม่คุ้นเคยกับแพลตฟอร์มนั้น ดังนั้นคำตอบนี้อาจจะไม่เกี่ยวข้องหรือไม่ก็ได้ ดังนั้นฉันจึงลบมันออก (ฉันได้ทดสอบสิ่งนี้ในแอปเดสก์ท็อป WPF ปกติและใช้งานได้ที่นั่น)   -  person pangabiMC    schedule 19.12.2015


คำตอบ (2)


ประการแรก ในการเพิ่มรูปร่างสี่เหลี่ยมผืนผ้า เราสามารถสร้างอินสแตนซ์ของ StackPanel และจัดการองค์ประกอบย่อยได้:

for (var i = 0; i < 5; i++) // The 5 here could be any number
{
                StackPanel sp = new StackPanel
                {
                    Name = "myPanel" + i,
                    Orientation = Orientation.Horizontal
                };
                myStackPanel.Children.Add(sp);

                for (var j = 0; j < 10; j++) // The 10 here could be any number
                {
                    sp.Children.Add(new Rectangle
                    {
                        Name = "myRectangle" + i + "-" + j,
                        Fill = new SolidColorBrush(Colors.Black),
                        Width = 20,
                        Height = 20,
                        Margin = new Thickness(1)
                    });
                }
}

จากนั้นเพื่อให้สามารถเปลี่ยนสีเติมของสี่เหลี่ยมอันใดอันหนึ่งได้เมื่อฉันคลิกปุ่มเริ่มเป็นต้น ทั้งหมดในโค้ดเบื้องหลัง

ดังที่ tgpdyk กล่าวไว้ เราจำเป็นต้องใช้ VisualTreeHelper เพื่อค้นหารูปร่างสี่เหลี่ยมผืนผ้าที่ระบุ

คลาสผู้ช่วย:

public static class FrameworkElementExtensions
{
        public static T TraverseCTFindShape<T>(DependencyObject root, String name) where T : Windows.UI.Xaml.Shapes.Shape
        {
            T control = null;

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(root); i++)
            {
                var child = VisualTreeHelper.GetChild(root, i);

                string childName = child.GetValue(FrameworkElement.NameProperty) as string;
                control = child as T;

                if (childName == name)
                {
                    return control;
                }
                else
                {
                    control = TraverseCTFindShape<T>(child, name);

                    if (control != null)
                    {
                        return control;
                    }
                }
            }

            return control;
        }
}

วิธีใช้:

private void StartButton_Click(object sender, RoutedEventArgs e)
{
            // E.G. To change the Fill color of Rectangle4 in StackPanel2
            var rec = FrameworkElementExtensions.TraverseCTFindShape<Shape>(myStackPanel, "myRectangle" + 2 + "-" + 4);
            rec.Fill = new SolidColorBrush(Colors.Red);
}

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

ฉันได้อัปโหลดตัวอย่างของฉันไปที่ พื้นที่เก็บข้อมูล Github

person Franklin Chen - MSFT    schedule 19.12.2015

นั่น ไม่ใช่ วิธีที่คุณเข้าถึงสิ่งนี้ใน WPF เลย

โดยปกติแล้วคุณไม่ต้องกังวลกับองค์ประกอบ UI ใดๆ แต่เกี่ยวข้องกับข้อมูลเท่านั้น ในกรณีนี้ ข้อมูลของคุณผูก ItemsControl ไปยังรายการแถว แต่ละแถวประกอบด้วยรายการเซลล์ ในคำจำกัดความ ItemsControl คุณจะต้องตั้งค่า ItemTemplate ที่มี ItemsControl อีกอันเชื่อมโยงกับเซลล์ ใน ItemsControl ที่ซ้อนกัน คุณสามารถตั้งค่า ItemTemplate โดยที่คุณผูก Background กับ a (การแจ้งเตือน) คุณสมบัติของเซลล์ของคุณ ซึ่งคุณเพียงแค่ต้องเปลี่ยนโค้ด

ตรวจสอบภาพรวมเหล่านี้:

คุณอาจต้องการดูรูปแบบ Model-View-ViewModel เพื่อให้แน่ใจว่าสถาปัตยกรรมแอปพลิเคชันเหมาะสม

person H.B.    schedule 20.12.2015
comment
ต่อไปนี้คือภาพรวมการผูกข้อมูลเฉพาะ UWP ส่วนใหญ่ถ้าไม่ใช่ทุกอย่างก็ควรจะคล้ายคลึงกันอยู่แล้ว - person H.B.; 20.12.2015
comment
ขอบคุณสำหรับข้อมูลของคุณที่นี่ ฉันทำเครื่องหมาย @Franklin Chen - MSFT เป็นคำตอบเนื่องจากตอบคำถามของฉันโดยเฉพาะ อย่างไรก็ตาม การนำไปปฏิบัติทำให้ฉันตระหนักว่าวิธีที่ฉันกำลังแก้ไขปัญหาอาจไม่ใช่วิธีที่ดีที่สุด ความจริงที่ว่ามันวนซ้ำผ่านสี่เหลี่ยมทั้งหมดเพื่อค้นหาเป้าหมายนั้นใช้เวลานานเกินไปเมื่อมีสี่เหลี่ยมหลายแถว ฉันจะดูข้อมูลอ้างอิงที่คุณให้ไว้และพยายามดำเนินการต่อไป ในระหว่างนี้ หากคุณมีเวลาว่าง ก็น่าสนใจที่จะได้เห็นวิธีแก้ปัญหาของคุณ ทั้งสำหรับฉันและคนอื่นๆ ที่กำลังดิ้นรนในลักษณะเดียวกัน - person gaw; 20.12.2015
comment
การค้นหาเป้าหมายที่คุณต้องการโต้ตอบด้วยอย่างมีประสิทธิภาพนั้นค่อนข้างเป็นปัญหาที่แตกต่างออกไป และมักจะไม่เป็นปัญหาหากคุณใช้แนวทางของฉัน มันมาจากการเข้าถึงอาร์เรย์สองครั้ง (หนึ่งรายการสำหรับแถว และอีกรายการหนึ่งสำหรับเซลล์ในแถวดังกล่าว) เมื่อคุณเข้าใจพื้นฐานของ WPF แล้ว การใช้งานคำอธิบายของฉันก็ไม่สำคัญเลย ตอนนี้ฉันไม่มีสภาพแวดล้อมที่สามารถนำสิ่งนี้ไปใช้ได้อย่างน่าเสียดาย - person H.B.; 22.12.2015