Buat StackPanels secara dinamis dan rujuk salah satu dari mereka dalam kode di belakang

Dalam bentuknya yang paling sederhana...

Saya ingin membuat StackPanel sebanyak yang saya inginkan dan kemudian menambahkan Rectangles di dalamnya. Kemudian untuk dapat mengubah warna Isi salah satu Persegi Panjang ketika saya mengklik Tombol Mulai misalnya. Semua dalam Kode Dibalik.

Bantuan apa pun akan dihargai.

Misalnya, jika bir favorit kita memiliki kerangka kerja saya dapat melakukannya seperti ini:

XAML:

<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>

Kode Dibalik:

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 sumber
comment
Ini akan memandu Anda. stackoverflow.com/questions/874380/ .. Anda hanya perlu memodifikasinya sedemikian rupa sehingga Anda memenuhi syarat nama dalam menambah dan memodifikasi properti. Dan tentu saja, Anda harus menggunakan VisualTreeHelper.   -  person tgpdyk    schedule 19.12.2015
comment
Oke terima kasih @tgpdyk, saya akan memeriksanya.   -  person gaw    schedule 19.12.2015
comment
@tgpdyk Sepertinya saya mendapatkan kesalahan saat mencoba salah satu dari ini: Argumen 1: tidak dapat mengonversi dari 'Windows.UI.Composition.Visual' ke 'Windows.UI.Xaml.DependencyObject' - Saya sering menemukan ini ketika merujuk ke dokumen lain. Bisakah Anda (atau siapa pun) lebih spesifik - Pemula di sini : (   -  person gaw    schedule 19.12.2015
comment
@gaw Maaf, saya tidak menyadarinya uwp, saya tidak familiar dengan platform itu jadi jawaban ini mungkin tidak relevan atau tidak, jadi saya menghapusnya. (Saya mengujinya pada aplikasi desktop WPF normal dan berfungsi di sana).   -  person pangabiMC    schedule 19.12.2015


Jawaban (2)


Pertama, untuk menambahkan bentuk Rectangle, kita dapat membuat instance StackPanel dan memanipulasi elemen Children-nya:

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)
                    });
                }
}

Kemudian untuk dapat mengubah warna Isi salah satu Persegi Panjang ketika saya mengklik Tombol Mulai misalnya. Semua dalam Kode Dibalik.

Seperti yang disebutkan tgpdyk, kita perlu menggunakan VisualTreeHelper untuk menemukan bentuk persegi panjang yang ditentukan.

Kelas pembantu:

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;
        }
}

Bagaimana cara menggunakannya:

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);
}

masukkan deskripsi gambar di sini

Saya telah mengunggah sampel saya ke repositori Github

person Franklin Chen - MSFT    schedule 19.12.2015

Itu bukan cara Anda melakukan pendekatan ini di WPF.

Anda biasanya tidak memikirkan komponen UI apa pun tetapi hanya datanya. Dalam hal ini data Anda mengikat ItemsControl ke daftar baris, setiap baris berisi daftar sel. Dalam definisi ItemsControl Anda kemudian menetapkan rel ItemTemplate yang berisi ItemsControl lain yang mengikat sel. Di ItemsControl bersarang Anda kemudian dapat menyetel ItemTemplate tempat Anda mengikat Background ke (notifying) properti sel Anda yang kemudian hanya perlu Anda ubah kodenya.

Lihat ikhtisar ini:

Anda mungkin juga ingin melihat pola Model-View-ViewModel untuk memastikan arsitektur aplikasi yang sesuai.

person H.B.    schedule 20.12.2015
comment
Berikut adalah ikhtisar pengikatan data khusus UWP. Namun sebagian besar, jika tidak semuanya, harus dianalogikan. - person H.B.; 20.12.2015
comment
Terima kasih atas masukan Anda di sini. Saya menandai @Franklin Chen - MSFT sebagai jawabannya karena menjawab pertanyaan saya dengan sangat spesifik. Namun penerapannya membuat saya menyadari bahwa cara saya menangani masalah mungkin bukan cara terbaik. Fakta bahwa ia melakukan iterasi melalui semua persegi panjang untuk menemukan target memakan waktu terlalu lama jika terdapat banyak baris dari banyak persegi panjang. Saya akan memeriksa referensi yang Anda berikan dan terus berjuang. Sementara itu, jika Anda memiliki waktu luang, akan menarik untuk melihat solusi Anda, baik bagi saya maupun orang lain yang mengalami kesulitan serupa. - person gaw; 20.12.2015
comment
Menemukan target yang ingin Anda ajak berinteraksi secara efisien adalah masalah yang agak berbeda dan biasanya tidak menjadi masalah jika Anda mengambil pendekatan saya; itu tergantung pada dua akses array (satu untuk baris, satu lagi untuk sel di baris tersebut). Setelah Anda memahami dasar-dasar WPF, penerapan uraian saya sangatlah sepele. Sayangnya saat ini saya tidak memiliki lingkungan di mana saya dapat menerapkannya. - person H.B.; 22.12.2015