Làm thế nào để nhận TẤT CẢ các điều khiển con của biểu mẫu Windows Forms của một loại cụ thể (Nút / Hộp văn bản)?


120

Tôi cần nhận tất cả các điều khiển trên một biểu mẫu thuộc loại x. Tôi khá chắc chắn rằng tôi đã thấy mã đó một lần trong quá khứ sử dụng một cái gì đó như thế này:

dim ctrls() as Control
ctrls = Me.Controls(GetType(TextBox))

Tôi biết tôi có thể lặp lại tất cả các điều khiển để nhận trẻ em bằng cách sử dụng một hàm đệ quy, nhưng có điều gì đó dễ dàng hơn hoặc đơn giản hơn, có thể như sau không?

Dim Ctrls = From ctrl In Me.Controls Where ctrl.GetType Is Textbox

Câu trả lời:


232

Đây là một lựa chọn khác dành cho bạn. Tôi đã thử nghiệm nó bằng cách tạo một ứng dụng mẫu, sau đó tôi đặt một GroupBox và một GroupBox bên trong GroupBox ban đầu. Bên trong GroupBox lồng nhau, tôi đặt 3 điều khiển TextBox và một nút. Đây là mã tôi đã sử dụng (thậm chí bao gồm đệ quy bạn đang tìm kiếm)

public IEnumerable<Control> GetAll(Control control,Type type)
{
    var controls = control.Controls.Cast<Control>();

    return controls.SelectMany(ctrl => GetAll(ctrl,type))
                              .Concat(controls)
                              .Where(c => c.GetType() == type);
}

Để kiểm tra nó trong sự kiện tải biểu mẫu, tôi muốn đếm tất cả các điều khiển bên trong GroupBox ban đầu

private void Form1_Load(object sender, EventArgs e)
{
    var c = GetAll(this,typeof(TextBox));
    MessageBox.Show("Total Controls: " + c.Count());
}

Và nó trả về số lượng thích hợp mỗi lần, vì vậy tôi nghĩ điều này sẽ hoạt động hoàn hảo cho những gì bạn đang tìm kiếm :)


21
GetAll () định nghĩa ở đây là một ứng cử viên rất tốt cho một phương pháp mở rộng cho lớp Control
Michael Bahig

Tôi thích cách bạn sử dụng biểu thức lambda. Tìm hiểu chi tiết về biểu thức lambda ở đâu?
Aditya Bokade

"'System.Windows.Forms.Control.ControlCollection" không chứa định nghĩa cho' Cast 'và không có phương thức mở rộng nào' Cast 'chấp nhận đối số đầu tiên của loại' System.Windows.Forms.Control.ControlCollection '(là bạn thiếu một chỉ thị đang sử dụng hoặc một tham chiếu hợp ngữ?) "Tôi đang sử dụng .NET 4.5 và" Điều khiển "không có chức năng / phương thức / bất cứ điều gì" Truyền ". Tôi đang thiếu gì?
soulblazer

2
@soulblazer Thêm không gian tên System.Linq.
Ivan-Mark Debono,

var allCtl = GetAll (this.FindForm (), typeof (TextBox)); // đây là Usercontrol trả về Không có gì !!
bh_earth0

33

Trong C # (vì bạn đã gắn thẻ nó như vậy), bạn có thể sử dụng biểu thức LINQ như sau:

List<Control> c = Controls.OfType<TextBox>().Cast<Control>().ToList();

Chỉnh sửa cho đệ quy:

Trong ví dụ này, trước tiên bạn tạo danh sách các điều khiển và sau đó gọi một phương thức để điền nó. Vì phương thức này là đệ quy nên nó không trả về danh sách mà chỉ cập nhật nó.

List<Control> ControlList = new List<Control>();
private void GetAllControls(Control container)
{
    foreach (Control c in container.Controls)
    {
        GetAllControls(c);
        if (c is TextBox) ControlList.Add(c);
    }
}

Có thể thực hiện điều này trong một câu lệnh LINQ bằng cách sử dụng Descendantshàm, mặc dù tôi không quen thuộc với nó. Xem trang này để biết thêm thông tin về điều đó.

Chỉnh sửa 2 để trả lại một bộ sưu tập:

Như @ProfK đã đề xuất, một phương pháp chỉ trả về các điều khiển mong muốn có lẽ là phương pháp tốt hơn. Để minh họa điều này, tôi đã sửa đổi mã như sau:

private IEnumerable<Control> GetAllTextBoxControls(Control container)
{
    List<Control> controlList = new List<Control>();
    foreach (Control c in container.Controls)
    {
        controlList.AddRange(GetAllTextBoxControls(c));
        if (c is TextBox)
            controlList.Add(c);
    }
    return controlList;
}

Cảm ơn, C # hoặc VB là tốt cho tôi. Nhưng vấn đề là Controls.OfType <TExtbox> chỉ trả về các phần tử con của điều khiển hiện tại (trong trường hợp của tôi là Biểu mẫu) và tôi muốn trong một lệnh gọi để nhận TẤT CẢ các điều khiển trong Forma "một cách đệ quy" (chiilds, sub-child , sub-sub con, .....) trong asingle collection.
Luis

Tôi mong đợi một phương thức có tên là GetAllControls trả về một tập hợp các điều khiển mà tôi sẽ gán cho ControlList. Chỉ có vẻ thực hành tốt hơn.
ProfK

@ProfK Tôi đồng ý với bạn; thay đổi ví dụ cho phù hợp.
JYelton

13

Đây là một phiên bản cải tiến của GetAllControls () đệ quy thực sự hoạt động trên các vars riêng:

    private void Test()
    {
         List<Control> allTextboxes = GetAllControls(this);
    }
    private List<Control> GetAllControls(Control container, List<Control> list)
    {
        foreach (Control c in container.Controls)
        {
            if (c is TextBox) list.Add(c);
            if (c.Controls.Count > 0)
                list = GetAllControls(c, list);
        }

        return list;
    }
    private List<Control> GetAllControls(Control container)
    {
        return GetAllControls(container, new List<Control>());
    }

10

Tôi đã kết hợp một loạt các ý tưởng trước đó thành một phương pháp mở rộng. Những lợi ích ở đây là bạn nhận được trở lại kiểu liệt kê được nhập chính xác, cộng với việc thừa kế được xử lý chính xác bởi OfType().

public static IEnumerable<T> FindAllChildrenByType<T>(this Control control)
{
    IEnumerable<Control> controls = control.Controls.Cast<Control>();
    return controls
        .OfType<T>()
        .Concat<T>(controls.SelectMany<Control, T>(ctrl => FindAllChildrenByType<T>(ctrl)));
}

5

Bạn có thể sử dụng truy vấn LINQ để thực hiện việc này. Thao tác này sẽ truy vấn mọi thứ trên biểu mẫu được nhập TextBox

var c = from controls in this.Controls.OfType<TextBox>()
              select controls;

Cảm ơn, nhưng vấn đề tương tự như câu trả lời ther, nó chỉ trả về chidls chứ không trả về con, v.v. và tôi muốn tất cả các điều khiển kèm theo. Tôi khá chắc chắn rằng tôi đã thấy rằng nó có thể thực hiện được với một cuộc gọi phương thức duy nhất mới trong .NET 3.5 hoặc 4.0, hãy nhớ rằng tôi đã thấy điều đó trong một bản demo nào đó
Luis

Bỏ qua việc thiếu đệ quy, sẽ không var c = this.Controls.OfType<TextBox>()cho kết quả tương tự?
CoderDennis

2
@Dennis: Đúng vậy, đó là vấn đề sở thích (thông thường). Xem stackoverflow.com/questions/214500/… để có một cuộc thảo luận thú vị về vấn đề này.
JYelton

5

Nó có thể là một kỹ thuật cổ xưa, nhưng nó hoạt động như một sự quyến rũ. Tôi đã sử dụng đệ quy để thay đổi màu của tất cả các nhãn của điều khiển. Nó hoạt động tuyệt vời.

internal static void changeControlColour(Control f, Color color)
{
    foreach (Control c in f.Controls)
    {

        // MessageBox.Show(c.GetType().ToString());
        if (c.HasChildren)
        {
            changeControlColour(c, color);
        }
        else
            if (c is Label)
            {
                Label lll = (Label)c;
                lll.ForeColor = color;
            }
    }
}

4

Tôi muốn sửa đổi câu trả lời của PsychoCoders: vì người dùng muốn có được tất cả các quyền kiểm soát của một loại nhất định, chúng tôi có thể sử dụng generic theo cách sau:

    public IEnumerable<T> FindControls<T>(Control control) where T : Control
    {
        // we can't cast here because some controls in here will most likely not be <T>
        var controls = control.Controls.Cast<Control>();

        return controls.SelectMany(ctrl => FindControls<T>(ctrl))
                                  .Concat(controls)
                                  .Where(c => c.GetType() == typeof(T)).Cast<T>();
    }

Bằng cách này, chúng ta có thể gọi hàm như sau:

private void Form1_Load(object sender, EventArgs e)
{
    var c = FindControls<TextBox>(this);
    MessageBox.Show("Total Controls: " + c.Count());
}

Đây là giải pháp tốt nhất (và nhanh nhất theo thử nghiệm của tôi) theo ý kiến ​​của tôi trên trang này. Nhưng tôi khuyên bạn nên thay đổi các điều khiển thành một mảng: var enumerable = control as Control [] ?? điều khiển.ToArray (); và sau đó thay đổi thành: return enumerable.SelectMany (FindControls <T>) .Concat (enumerable) .Where (c => c.GetType () == typeof (T)). Cast <T> ();
Randall Flagg

Sử dụng .OfType<T>()phương pháp Linq không hiệu quả hơn là .Where(c => c.GetType() == typeof(T)).Cast<T>();để có được hiệu quả tương tự?
TheHitchenator

3

Đừng quên rằng bạn cũng có thể có TextBox trong các điều khiển khác ngoài điều khiển vùng chứa. Bạn thậm chí có thể thêm TextBox vào PictureBox.

Vì vậy, bạn cũng cần kiểm tra xem

someControl.HasChildren = True

trong bất kỳ hàm đệ quy nào.

Đây là kết quả tôi có được từ một bố cục để kiểm tra mã này:

TextBox13   Parent = Panel5
TextBox12   Parent = Panel5
TextBox9   Parent = Panel2
TextBox8   Parent = Panel2
TextBox16   Parent = Panel6
TextBox15   Parent = Panel6
TextBox14   Parent = Panel6
TextBox10   Parent = Panel3
TextBox11   Parent = Panel4
TextBox7   Parent = Panel1
TextBox6   Parent = Panel1
TextBox5   Parent = Panel1
TextBox4   Parent = Form1
TextBox3   Parent = Form1
TextBox2   Parent = Form1
TextBox1   Parent = Form1
tbTest   Parent = myPicBox

Hãy thử điều này với một Nútmột RichTextBox trên một biểu mẫu.

Option Strict On
Option Explicit On
Option Infer Off

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim pb As New PictureBox
        pb.Name = "myPicBox"
        pb.BackColor = Color.Goldenrod
        pb.Size = New Size(100, 100)
        pb.Location = New Point(0, 0)
        Dim tb As New TextBox
        tb.Name = "tbTest"
        pb.Controls.Add(tb)
        Me.Controls.Add(pb)

        Dim textBoxList As New List(Of Control)
        textBoxList = GetAllControls(Of TextBox)(Me)

        Dim sb As New System.Text.StringBuilder
        For index As Integer = 0 To textBoxList.Count - 1
            sb.Append(textBoxList.Item(index).Name & "   Parent = " & textBoxList.Item(index).Parent.Name & System.Environment.NewLine)
        Next

        RichTextBox1.Text = sb.ToString
    End Sub

    Private Function GetAllControls(Of T)(ByVal searchWithin As Control) As List(Of Control)

        Dim returnList As New List(Of Control)

        If searchWithin.HasChildren = True Then
            For Each ctrl As Control In searchWithin.Controls
                If TypeOf ctrl Is T Then
                    returnList.Add(ctrl)
                End If
                returnList.AddRange(GetAllControls(Of T)(ctrl))
            Next
        ElseIf searchWithin.HasChildren = False Then
            For Each ctrl As Control In searchWithin.Controls
                If TypeOf ctrl Is T Then
                    returnList.Add(ctrl)
                End If
                returnList.AddRange(GetAllControls(Of T)(ctrl))
            Next
        End If
        Return returnList
    End Function

End Class

2

Sử dụng phản xạ:

// Return a list with all the private fields with the same type
List<T> GetAllControlsWithTypeFromControl<T>(Control parentControl)
{
    List<T> retValue = new List<T>();
    System.Reflection.FieldInfo[] fields = parentControl.GetType().GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
    foreach (System.Reflection.FieldInfo field in fields)
    {
      if (field.FieldType == typeof(T))
        retValue.Add((T)field.GetValue(parentControl));
    }
}

List<TextBox> ctrls = GetAllControlsWithTypeFromControl<TextBox>(this);

2

Đây là phương pháp mở rộng của tôi Control, sử dụng LINQ, như một bản chuyển thể của phiên bản @PsychoCoder :

Thay vào đó, nó có một danh sách loại cho phép bạn không cần nhiều cuộc gọi GetAllđể có được những gì bạn muốn. Tôi hiện đang sử dụng nó như một phiên bản quá tải.

public static IEnumerable<Control> GetAll(this Control control, IEnumerable<Type> filteringTypes)
{
    var ctrls = control.Controls.Cast<Control>();

    return ctrls.SelectMany(ctrl => GetAll(ctrl, filteringTypes))
                .Concat(ctrls)
                .Where(ctl => filteringTypes.Any(t => ctl.GetType() == t));
}

Sử dụng:

//   The types you want to select
var typeToBeSelected = new List<Type>
{
    typeof(TextBox)
    , typeof(MaskedTextBox)
    , typeof(Button)
};

//    Only one call
var allControls = MyControlThatContainsOtherControls.GetAll(typeToBeSelected);

//    Do something with it
foreach(var ctrl in allControls)
{
    ctrl.Enabled = true;
}

2

Một giải pháp sạch sẽ và dễ dàng (C #):

static class Utilities {
    public static List<T> GetAllControls<T>(this Control container) where T : Control {
        List<T> controls = new List<T>();
        if (container.Controls.Count > 0) {
            controls.AddRange(container.Controls.OfType<T>());
            foreach (Control c in container.Controls) {
                controls.AddRange(c.GetAllControls<T>());
            }
        }

        return controls;
    }
}

Nhận tất cả các hộp văn bản:

List<TextBox> textboxes = myControl.GetAllControls<TextBox>();

2

Bạn có thể sử dụng Mã bên dưới

public static class ExtensionMethods
{
    public static IEnumerable<T> GetAll<T>(this Control control)
    {
        var controls = control.Controls.Cast<Control>();

        return controls.SelectMany(ctrl => ctrl.GetAll<T>())
                                  .Concat(controls.OfType<T>());
    }
}

2

Đây là phương pháp Mở rộng của tôi. Nó rất hiệu quả và nó lười biếng.

Sử dụng:

var checkBoxes = tableLayoutPanel1.FindChildControlsOfType<CheckBox>();

foreach (var checkBox in checkBoxes)
{
    checkBox.Checked = false;
}

Mã là:

public static IEnumerable<TControl> FindChildControlsOfType<TControl>(this Control control) where TControl : Control
    {
        foreach (var childControl in control.Controls.Cast<Control>())
        {
            if (childControl.GetType() == typeof(TControl))
            {
                yield return (TControl)childControl;
            }
            else
            {
                foreach (var next in FindChildControlsOfType<TControl>(childControl))
                {
                    yield return next;
                }
            }
        }
    }

đây là một phiên bản gọn gàng hơn, lười biếng, có thể được liệt kê và tìm nạp theo yêu cầu.
Jone Polvora


1
public List<Control> GetAllChildControls(Control Root, Type FilterType = null)
{
    List<Control> AllChilds = new List<Control>();
    foreach (Control ctl in Root.Controls) {
        if (FilterType != null) {
            if (ctl.GetType == FilterType) {
                AllChilds.Add(ctl);
            }
        } else {
            AllChilds.Add(ctl);
        }
        if (ctl.HasChildren) {
            GetAllChildControls(ctl, FilterType);
        }
    }
    return AllChilds;
}

1
   IEnumerable<Control> Ctrls = from Control ctrl in Me.Controls where ctrl is TextBox | ctrl is GroupBox select ctr;

Biểu thức Lambda

IEnumerable<Control> Ctrls = Me.Controls.Cast<Control>().Where(c => c is Button | c is GroupBox);

Vui lòng bổ sung thêm vào câu trả lời của bạn giải thích điều gì đang xảy ra và nó liên quan đến câu hỏi như thế nào.
Fencer04,

0

Tôi đã sửa đổi từ @PsychoCoder. Tất cả các điều khiển có thể được tìm thấy ngay bây giờ (bao gồm lồng nhau).

public static IEnumerable<T> GetChildrens<T>(Control control)
{
  var type = typeof (T);

  var allControls = GetAllChildrens(control);

  return allControls.Where(c => c.GetType() == type).Cast<T>();
}

private static IEnumerable<Control> GetAllChildrens(Control control)
{
  var controls = control.Controls.Cast<Control>();
  return controls.SelectMany(c => GetAllChildrens(c))
    .Concat(controls);
}

0

Điều này có thể hoạt động:

Public Function getControls(Of T)() As List(Of T)
    Dim st As New Stack(Of Control)
    Dim ctl As Control
    Dim li As New List(Of T)

    st.Push(Me)

    While st.Count > 0
        ctl = st.Pop
        For Each c In ctl.Controls
            st.Push(CType(c, Control))
            If c.GetType Is GetType(T) Then
                li.Add(CType(c, T))
            End If
        Next
    End While

    Return li
End Function

Tôi nghĩ rằng chức năng nhận tất cả các điều khiển mà bạn đang nói đến chỉ có sẵn cho WPF .


0

Đây là một giải pháp chung đã được thử nghiệm và hoạt động:

Tôi có một số lượng lớn các điều khiển UpDownNumeric, một số ở biểu mẫu chính, một số ở hộp nhóm trong biểu mẫu. Tôi chỉ muốn một điều khiển được chọn cuối cùng thay đổi màu nền thành màu xanh lục, mà lần đầu tiên tôi đặt tất cả các điều khiển khác thành màu trắng, sử dụng phương pháp này: (cũng có thể mở rộng cho cháu)

    public void setAllUpDnBackColorWhite()
    {
        //To set the numericUpDown background color of the selected control to white: 
        //and then the last selected control will change to green.

        foreach (Control cont in this.Controls)
        {
           if (cont.HasChildren)
            {
                foreach (Control contChild in cont.Controls)
                    if (contChild.GetType() == typeof(NumericUpDown))
                        contChild.BackColor = Color.White;
            }
            if (cont.GetType() == typeof(NumericUpDown))
                cont.BackColor = Color.White;
       }
    }   

Điều này không hiệu quả nếu kiểm soát trẻ em có trẻ em của riêng nó.
soulblazer

0

Bạn có thể thử điều này nếu bạn muốn :)

    private void ClearControls(Control.ControlCollection c)
    {
        foreach (Control control in c)
        {
            if (control.HasChildren)
            {
                ClearControls(control.Controls);
            }
            else
            {
                if (control is TextBox)
                {
                    TextBox txt = (TextBox)control;
                    txt.Clear();
                }
                if (control is ComboBox)
                {
                    ComboBox cmb = (ComboBox)control;
                    if (cmb.Items.Count > 0)
                        cmb.SelectedIndex = -1;
                }

                if (control is CheckBox)
                {
                    CheckBox chk = (CheckBox)control;
                    chk.Checked = false;
                }

                if (control is RadioButton)
                {
                    RadioButton rdo = (RadioButton)control;
                    rdo.Checked = false;
                }

                if (control is ListBox)
                {
                    ListBox listBox = (ListBox)control;
                    listBox.ClearSelected();
                }
            }
        }
    }
    private void btnClear_Click(object sender, EventArgs e)
    {
        ClearControls((ControlCollection)this.Controls);
    }

1
Đơn giản chỉ cần đăng mã không giúp OP hiểu được vấn đề của họ hoặc giải pháp của bạn. Bạn hầu như LUÔN LUÔN phải bao gồm một số loại giải thích để đi kèm với mã của bạn.
leigero

Câu hỏi không nói gì về việc xóa biểu mẫu.
LarsTech

Có, không trả lời "câu hỏi", nhưng là một bổ sung tốt cho nó. Cảm ơn bạn!

0

Mặc dù một số người dùng khác đã đăng các giải pháp thích hợp, nhưng tôi muốn đăng một cách tiếp cận chung hơn có thể hữu ích hơn.

Điều này phần lớn dựa trên phản hồi của JYelton.

public static IEnumerable<Control> AllControls(
    this Control control, 
    Func<Control, Boolean> filter = null) 
{
    if (control == null)
        throw new ArgumentNullException("control");
    if (filter == null)
        filter = (c => true);

    var list = new List<Control>();

    foreach (Control c in control.Controls) {
        list.AddRange(AllControls(c, filter));
        if (filter(c))
            list.Add(c);
    }
    return list;
}

0
    public static IEnumerable<T> GetAllControls<T>(this Control control) where T : Control
    {
        foreach (Control c in control.Controls)
        {
            if (c is T)
                yield return (T)c;
            foreach (T c1 in c.GetAllControls<T>())
                yield return c1;
        }
    }

0
    public IEnumerable<T> GetAll<T>(Control control) where T : Control
    {
        var type = typeof(T);
        var controls = control.Controls.Cast<Control>().ToArray();
        foreach (var c in controls.SelectMany(GetAll<T>).Concat(controls))
            if (c.GetType() == type) yield return (T)c;
    }

0

Đối với bất kỳ ai đang tìm kiếm phiên bản VB của mã C # của Adam được viết dưới dạng phần mở rộng của Controllớp:

''' <summary>Collects child controls of the specified type or base type within the passed control.</summary>
''' <typeparam name="T">The type of child controls to include. Restricted to objects of type Control.</typeparam>
''' <param name="Parent">Required. The parent form control.</param>
''' <returns>An object of type IEnumerable(Of T) containing the control collection.</returns>
''' <remarks>This method recursively calls itself passing child controls as the parent control.</remarks>
<Extension()>
Public Function [GetControls](Of T As Control)(
    ByVal Parent As Control) As IEnumerable(Of T)

    Dim oControls As IEnumerable(Of Control) = Parent.Controls.Cast(Of Control)()
    Return oControls.SelectMany(Function(c) GetControls(Of T)(c)).Concat(oControls.Where(Function(c) c.GetType() Is GetType(T) Or c.GetType().BaseType Is GetType(T))
End Function

LƯU Ý: Tôi đã thêm BaseType đối sánh cho bất kỳ điều khiển tùy chỉnh bắt nguồn nào. Bạn có thể loại bỏ điều này hoặc thậm chí đặt nó thành một tham số tùy chọn nếu bạn muốn.

Sử dụng

Dim oButtons As IEnumerable(Of Button) = Me.GetControls(Of Button)()

0

Tạo phương pháp

public static IEnumerable<Control> GetControlsOfType<T>(Control control)
{
    var controls = control.Controls.Cast<Control>();
    return controls.SelectMany(ctrl => GetControlsOfType<T>(ctrl)).Concat(controls).Where(c => c is T);
}

Và sử dụng nó Thích

Var controls= GetControlsOfType<TextBox>(this);//You can replace this with your control

0

Tôi đang sử dụng VB vì vậy, tôi đã viết một phương thức mở rộng. Điều đó truy xuất tất cả các con và con của một điều khiển

Imports System.Runtime.CompilerServices
Module ControlExt

<Extension()>
Public Function GetAllChildren(Of T As Control)(parentControl As Control) As IEnumerable(Of T)
    Dim controls = parentControl.Controls.Cast(Of Control)
    Return controls.SelectMany(Of Control)(Function(ctrl) _
        GetAllChildren(Of T)(ctrl)) _
        .Concat(controls) _
        .Where(Function(ctrl) ctrl.GetType() = GetType(T)) _
    .Cast(Of T)
End Function

End Module

Sau đó, bạn có thể sử dụng nó như, trong đó "btnList" là một điều khiển

btnList.GetAllChildren(Of HtmlInputRadioButton).FirstOrDefault(Function(rb) rb.Checked)

Trong trường hợp này, nó sẽ chọn nút radio đã chọn.


-1

Đơn giản:

For Each ctrl In Me.Controls.OfType(Of Button)()
   ctrl.Text = "Hello World!"
Next

Điều này sẽ chỉ tìm thấy các điều khiển trực tiếp trong bộ sưu tập điều khiển của "Tôi" và không tìm thấy các điều khiển Nút nằm trong bất kỳ vùng chứa con nào như người đăng cố gắng ám chỉ "TẤT CẢ".
ChrisPBacon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.