0

У меня есть xml файл

<Users>
<UserName>Человек1</UserName>
<UserPass>Пароль1</UserPass>

В нем хранится логин и пароль.

Логин, выводится в combobox

Там мы должны выбрать какой-то логин. И чтобы упростить задачу, скажу так... В другую строку, нужно вывести его сопутствующий пароль. Как это сделать, понятия не имею. xml я наполнял с помощью linq.

void XMLRes()
    {
        foreach (XElement phoneElement in xdoc.Element("Users").Elements("Users"))
        {
            XElement companyElement = phoneElement.Element("UserName");
            XElement priceElement = phoneElement.Element("UserPass");
        if (companyElement != null &amp;&amp; priceElement != null)
        {
            cmBoxUsers.Items.Add(companyElement.Value);
        }
    }
}

Подскажите пожалуйста.. В класс лезть не хочу. Не совсем понимаю(

введите сюда описание изображения

Espoit
  • 43
  • 6
  • На всякий случай, пароли не хранят в открытом виде, не забывайте хешировать. И JSON лучше, легче и проще, чем XML. – aepot Oct 04 '21 at 16:25
  • Создайте модель данных, класс Users, заведите в нем 2 свойства UserName и UserPass и десереализуйте в массив. Операция настолько простая, что я удивлен, что вы не нашли решения. Я как минимум несколько раз их здесь постил. Например вот. Не бойтесь использовать ООП. – aepot Oct 04 '21 at 16:36
  • Да, шифрование в релизе ставлю, когда все готово. Ну а если кроме класса, ничего нельзя, то ладно( Придется возвращаться и разбираться. Я класс то сделал. Но он только Записывает. А если внести новое значение, то файл перезаписывается. Оно и логично – Espoit Oct 04 '21 at 17:14
  • Ну почему нельзя, можно, просто сложнее. Мне бы было лень. – aepot Oct 04 '21 at 17:20
  • @aepot здравствуйте. Не хотел бы засорять топик своими тупыми вопросами, но хотел бы узнать у вас. Я использовал библиотеку MaterialStyle, которая добавляет кнопки и т.п в стиле MaterialDesign, и все круто, но она очень криво работает в 7й винде. Вообще отврат. Все криво нарисовано. Возможно ли при узнавании версии ОС, заменять элементы? Хуже всего, смотрится Panel.Теней нет, вместо них треш. И как то автоматом заменить Material Panel на другую? Спасибо – Espoit Oct 11 '21 at 08:07

1 Answers1

3

Начнём с того, что <UserPass>Пароль1</UserPass> - это элемент, а не атрибут.


Я бы предложил следующую структуру xml:

<Users>
  <User>
    <Name>Человек1</Name>
    <Pass>Пароль1</Pass>
  </User>
  <User>
    <Name>Человек2</Name>
    <Pass>Пароль2</Pass>
  </User>
</Users>

Элемент Users (во множественном числе) содержит множество элементов User (в единственном числе), каждый из которых представляет информацию об одном пользователе. Имена вложенных элементов сокращаем до Name и Pass, т. к. и так понятно, что они относятся к юзеру.

Названия всех методов и переменных в коде должны хорошо описывать своё предназначение. XMLRes - что делает этот метод? Из названия непонятно. Переименуем его, например, в LoadData.

Имена phoneElement, companyElement, priceElement вероятно остались от какого-то прежнего кода. Копипаста - зло! Переименуем их.


Сделаем класс, который будет содержать информацию о юзере. Таким образом данные об имени и пароле хранятся в одном объекте.

public class User
{
    public string Name { get; set; }
    public string Pass { get; set; }
}

Для хранения данных о пользователях сделаем поле:

private List<User> _users = new List<User>();

Код загрузки и привязки данных:

void LoadData()
{
    var xdoc = XDocument.Load("test.xml");
foreach (XElement userElement in xdoc.Element(&quot;Users&quot;).Elements(&quot;User&quot;))
{
    string name = userElement.Element(&quot;Name&quot;).Value;
    string pass = userElement.Element(&quot;Pass&quot;).Value;

    var user = new User { Name = name, Pass = pass };
    _users.Add(user);
}

comboBoxUsers.DisplayMember = nameof(User.Name);
comboBoxUsers.ValueMember = nameof(User.Pass);
comboBoxUsers.DataSource = _users;

textBoxPass.DataBindings.Add(nameof(TextBox.Text), _users, nameof(User.Pass));

}

На основе данных из xml создаём классы User и заносим их в коллекцию.
Делаем привязку этого списка к обоим контролам.
Комбобоксу задаём в DisplayMember, что он будет показывать имя пользователя. А в ValueMember задаём, какое значение он будет выдавать при выборе строки.

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


Вместо парсинга xml с помощью LINQ можно применить десериализацию. Но в данном случае это не имеет большого смысла, т. к. код и так лаконичен.

Вместо List<User>, возможно, следует испоьзовать BindingList<User> - при добавлении данных в эту коллекцию будет автоматически обновляться GUI.

  • 1
    Да. Это действительно так. Человеческое вам спасибо – Espoit Oct 05 '21 at 08:26
  • Десериализацию стоит показать, для будущих посетителей. А то будет "копипаста зло". В общем случае десереализация удобнее, проще и универсальнее, поддерживать код легче. Здесь конечно можно и без нее. – aepot Oct 05 '21 at 11:04