2015-06-29 3 views
1

Я беру XML, фильтруя и помещая его в поле со списком, и моя проблема берет выбранную запись combobox и сохраняет каждую отдельную часть. Вот пример использования XML-кода.combobox с несколькими переменными в одной строке, сохранение выбора

<SolutionString> 
    <Solutions> 
     <Solution> 
      <ID>1</ID> 
      <Property> 
      <Name>DriverSheave</Name> 
      <Value>1VP34</Value> 
      </Property> 
      <Property> 
      <Name>DriverBushing</Name> 
      <Value> 
      </Value> 
      </Property> 
      <Property> 
      <Name>DrivenSheave</Name> 
      <Value>AK49</Value> 
      </Property> 
      <Property> 
      <Name>DrivenBushing</Name> 
      <Value> 
      </Value> 
      </Property> 
     </Solution> 
     <Solution> 
      <ID>2</ID> 

... ect (ID 2, ID 3 и т. Д.). После этого я вставлял эти XML-результаты в мои комбобокс, как это.

XmlDocument doc1 = new XmlDocument(); 
doc1.LoadXml(XmlString.ToString()); 
PTS.Library.VbeltDriveLibrary.Configurator Configurator = new PTS.Library.VbeltDriveLibrary.Configurator(doc1); 
if (Configurator.SolveAndValidate()) 
{ 
    var solutions = Configurator.Results.ToXDocument(); 
    int i = 0; 
    var indexesToChoose = new List<int> { 9, 8, 4, 5, 0, 2, 7, 6 }; 
    var cat = solutions 
     .Descendants("Solution") 
     .Select(x => new 
     { 
      ID = (string)x.Element("ID"), 
      Properties = x.Elements("Property").Select(p => new 
      { 
       Name = (string) p.Element("Name"), 
       Value = (string) p.Element("Value"), 

       idx = (i < 11 ? i++ : i = 0) 
      }) 
      .Where(y => indexesToChoose.Contains(y.idx)) 
      .OrderBy(z => indexesToChoose.FindIndex(p => p == z.idx)) 
      .ToList() 
     }); 

    var items = cat 
     .Select(s => new 
     { 
      ID = s.ID, 
      Text = string.Format("{0}. {1}", s.ID, 
      string.Join(", ", s.Properties 
           .Select(p => string.Format("{0} = {1}", 
            p.Name, 
            p.Value ?? "(null)")))) 
     }).ToArray(); 
    comboBox1.DisplayMember = "Text"; 
    comboBox1.ValueMember = "ID"; 
    comboBox1.Items.AddRange(items); 

Наконец, я хочу, чтобы иметь возможность принять этот выбор, (это выбранные элементы в выпадающем списке)

  1. Стоимость = 1072,93, ActualDrivenShaftSpeed ​​= 900/1073, пояс = B84 , BeltQty = 5, DriverSheave = 5MVP70B84P, Comment2 = Правильное натяжение для этого привода (1,31 фунта на отклонение пояса 0,48 дюйма) будет иметь 30 фунтов «Эксплуатация» Нагрузка концентратора, DrivenSheave = 5MVB70R, ActualServiceFactor = 40,63, ActualCenterDistance = 30,8

и фильтровать каждый кусок из в переменный, например,

string ActualCenterDistance = 30.8 

Очевидно, я могу поставить весь выбор в строку легко с помощью простого combobox.selectedText, однако помещая каждую часть в отдельные строки (или любой другой вар) - моя проблема.

ответ

1

Это выглядит плохой дизайн для меня.

Рассмотрим вместо использования анонимного типа здесь:

.Select(x => new 
      { 
       ID = (string)x.Element("ID"), 
       Properties = x.Elements("Property").Select(p => new 

просто создать экземпляр своего собственного класса, который может быть как:

public class MyItem 
{ 
    public string ID; 
    public List<Tuple<string, string>> Properties; 

    public string GetProperty(string name) 
    { 
     if (Properties == null) 
      return null; 

     var item = Properties.FirstOrDefault(x => x.Item1 == name); 
     return item == null ? null : item.Item2; 
    } 

    public override string ToString() 
    { 
     return string.Join(", ", Properties 
      .Select(p => string.Format("{0} = {1}", 
       p.Item1, 
       p.Item2 ?? "(null)"))); 
    } 
} 

в этом случае (так как я перенесенного логику конкатенации Имя/Значение свойств для ToString метод переопределения класса MyItem) - вы можете заполнить combobox с элементами, имеющими тип MyItem, и вы сможете легко получить доступ ко всем своим данным:

var item = comboBox1.SelectedItem as MyItem; 
string x = item.GetProperty("DriverSheave"); 

Изменения должны быть сделаны с кодом:

var items = solutions.Descendants("Solution") 
    .Select(x => new MyItem 
    { 
     ID = (string)x.Element("ID"), 
     Properties = x.Elements("Property").Select(p => new 
     { 
      Name = (string)p.Element("Name"), 
      Value = (string)p.Element("Value"), 

      idx = (i < 11 ? i++ : i = 0) 
     }) 
     .Where(y => indexesToChoose.Contains(y.idx)) 
     .OrderBy(z => indexesToChoose.FindIndex(p => p == z.idx)) 
     .Select(z => new Tuple<string, string>(z.Name, z.Value)) 
     .ToList() 
    }).ToArray(); 


comboBox1.DisplayMember = "Text"; 
comboBox1.ValueMember = "ID"; 
comboBox1.Items.AddRange(items); 

Примечание: это принципиально важно иметь некоторый пользовательский класс как Item для выпадающего списка, потому что в случае анонимного типа используется не будет возможность доступа к своим полям при съемке объекта с combobox.SelectedItem.

+0

Как я могу фильтровать между элементами, когда я делаю 'combobox.SelectedItem'? Я хочу, чтобы иметь возможность взять каждую часть 'selectedItem' и поместить ее в свою строку или переменную, если это возможно, я могу просто пропустить ее в вашем ответе. \ –

+0

@AndrewKucenski' comboBox1.SelectedItem as MyItem' - будет один из «MyItems» использовался для заполнения combobox. Таким образом, вы можете его поле «Свойства» и сделать все, что хотите, с помощью этого списка. В вашем примере из вопроса - просто найдите в этом списке кортеж, имеющий 'Item1' (мы поместили« Имя »свойств из xml там, как вы помните) и верните этот tuple.Item2. Лучше добавить вспомогательный метод в класс 'MyItem', скажем,« GetProperty ». –

+0

ладно, так что с этим списком плохо можете просто взять Take say, Cost = 100, out? Также спасибо за такой подробный ответ. –

Смежные вопросы