Перебираем элементы управления разных типов и создаем конструктор строк для копирования - PullRequest
0 голосов
/ 13 июля 2020

Я не могу найти подобный вопрос или ответ на то, что я спрашиваю, но если он есть, я прошу прощения. Я хочу просто пропустить l oop через все мои элементы управления в пользовательском элементе управления, а затем записать в построитель строк в порядке l oop.

В приведенном ниже коде описывается простой пример, и я попробовал некоторые ограниченные вещи, основанные на том, что я знал C# et c.

<Window x:Class="CopyandPaste.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CopyandPaste"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid x:Name="MainGrid">
        <Button x:Name="CopyButton" Content="Copy Button" HorizontalAlignment="Left" Margin="10,34,0,0" VerticalAlignment="Top" RenderTransformOrigin="-4.265,-0.098" Height="41" Width="120" Click="CopyButton_Click"/>

        <Grid x:Name="MasterGrid" HorizontalAlignment="Left" Height="378" Margin="146,10,0,0" VerticalAlignment="Top" Width="572">

            <TextBox HorizontalAlignment="Center" Margin="0,21,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="408" Height="23" Grid.Column="1"/>
            <RadioButton x:Name="RadioButton" Content="RadioButton" HorizontalAlignment="Left" Margin="82,55,0,0" VerticalAlignment="Top" Height="15" Width="85"/>
            <ComboBox x:Name="ComboBox" HorizontalAlignment="Left" Margin="82,95,0,0" VerticalAlignment="Top" Width="369" Height="22">
                <ComboBoxItem>THIS IS IT 1</ComboBoxItem>
                <ComboBoxItem>THIS IS IT 2</ComboBoxItem>
                <ComboBoxItem>THIS IS IT 3</ComboBoxItem>
            </ComboBox>
            <TextBox HorizontalAlignment="Center" Margin="0,140,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="408" Height="23"/>
            <TextBox HorizontalAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Center" Width="408" RenderTransformOrigin="0.333,0.782" Height="28"/>


        </Grid>

    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace CopyandPaste
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();            
        }

        private void CopyButton_Click(object sender, RoutedEventArgs e)
        {
            bool first = true;

            StringBuilder value = new StringBuilder();

            // some loop here

            Clipboard.SetText(value.ToString());
        }
    }
}

Я играл с некоторыми циклами foreach, которые были вложенными, но, конечно, получил некоторые результаты, которые были нежелательными:

1
RadioButton
THIS IS IT 2
2
RadioButton
THIS IS IT 2
3
RadioButton
THIS IS IT 2

Я понимаю, что здесь происходит, когда текстовое поле вызывает продолжение l oop. Попытка получить некоторые идеи или точку в правильном направлении для достижения такого результата, как:

1
RadioButton
ЭТО ЭТО 2
2
3

1 Ответ

1 голос
/ 13 июля 2020

Любой WPF UIElement имеет свойство Children, которое предоставит вам все его дочерние элементы управления. Таким образом, вы можете использовать его для перечисления детей, а затем l oop через них. Что-то вроде;

foreach (var child in MasterGrid.Children)
{
    // string builder code
}

Вы не совсем ясно объяснили, каковы ваши критерии для отображения элемента управления, но из ограниченного объяснения, которое вы дали, похоже, что вы хотите получить свойство Text, если это TextBox, SelectedItem, если это ComboBox, и имя элемента управления, если это RadioButton. Когда дело доходит до элемента управления, это совершенно разные вещи, поэтому внутри l oop вам нужно будет проверить тип каждого дочернего элемента управления и получить правильную информацию.

private void CopyButton_Click(object sender, RoutedEventArgs e)
{
    StringBuilder value = new StringBuilder();
    foreach (var child in MasterGrid.Children.OfType<Control>())
    {
        if (child.GetType() == typeof(TextBox))
        {
            value.Append(((TextBox)child).Text + Environment.NewLine);
        }
        else if (child.GetType() == typeof(RadioButton))
        {
            var rb = (RadioButton)child;
            if (rb.IsChecked == true)
            {
                value.Append(rb.Name + Environment.NewLine);
            }
        }
        else if (child.GetType() == typeof(ComboBox))
        {
            value.Append(((ComboBox)child).Text + Environment.NewLine);
        }
    }
    MessageBox.Show(value.ToString());
}

Выше приведены типы элементов управления, о которых вы упомянули, вам придется выяснить, что делать с другими типами элементов управления.

Далее, когда дело доходит до порядка, в элементах управления в WPF могут быть разные значения «порядка». GUI.

  • Хотите ли вы порядок, в котором они указаны в коде XAML?
  • Или вы хотите порядок, в котором они отображаются, когда программа запускается?

Например, в вашем коде, если вы переместили последнее текстовое поле XAML код над предпоследним, они все равно будут отображаться в исходном порядке при запуске программы потому что вы жестко запрограммировали их расположение (что само по себе плохая идея; вы должны использовать сетки, панели стека и т. д. c, чтобы сделать макет в WPF).

Я думаю, если вам не все равно о порядке, лучший вариант - изменить y свой XAML и укажите свойство Tag каждого элемента управления.

Например,

<TextBox Grid.Column="1"
    Width="408"
    Height="23"
    Margin="0,21,0,0"
    HorizontalAlignment="Center"
    VerticalAlignment="Top"
    Tag="1"
    TextWrapping="Wrap"/>

Затем, когда вы перечисляете дочерние элементы, выполняйте порядок по тегам перед их итерацией.

Таким образом, у вас будет твердый контроль над тем, что вы подразумеваете под заказом.

var children = MasterGrid.Children.OfType<Control>().OrderBy(x => x.Tag);
foreach (var child in children)
{
    // Same as before
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...