我有两个组合框和xml文件,我想从xml中填充组合框1中的服务器名称并基于服务器名称填充第二个组合框

时间:2015-11-11 09:32:37

标签: c# xml wpf mvvm combobox

XML:

<?xml version="1.0" encoding="utf-8"?>

<servers>
    <server>s2
        <database>db1</database>
        <database>db2</database>    

    </server>

    <server>s3
        <database>db3</database>
        <database>db4</database>    

    </server>

</servers>
  

我想根据服务器名称获取数据库&amp;返回为字符串类型列表。

查看:

  

此函数将服务器名称作为第一个组合框中的参数并基于will过滤器数据库并填充第二个组合框

public List<string> GetDatabases(string serv)
       {          
           var item = from items in xdoc.Descendants("database")
                      where (string)items.Element("server") == serv
                      select items.Elements("database").ToList();                        
           foreach (var items in item)
           {
               lstDBName.Add(items.ToString());
           }               
           return lstDBName;

       }

2 个答案:

答案 0 :(得分:0)

您发布的XML无效。如果您使用XML validator对其进行测试,则会看到它出现此错误:

Errors in the XML document: 
    1:  1   Content is not allowed in prolog.

您可以通过添加属性来轻松修复它,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<servers>
    <server name="s2">
        <database>db1</database>
        <database>db2</database>    
    </server>
    <server name="s3">
        <database>db3</database>
        <database>db4</database>    
    </server>
</servers>

您可以像这样修改(并简化一下)代码:

public List<string> GetDatabases(string serv)
{
    XDocument xdoc = XDocument.Load("XMLFile1.xml");
    var lstDBName = (from items in xdoc.Descendants("server")
                     where items.Attribute("name").Value == serv
                     from item in items.Elements("database")
                     select item.Value)
                     .ToList();
    return lstDBName;
}

我从一个名为XMLFile1.xml的文件中读取方法中的XML,你可以在读取XML时更改该位。

此代码示例将返回两个字符串的列表,其值为“db1”和“db2”,如预期的那样

答案 1 :(得分:0)

根据我的理解,您需要一些机制,在第一个组合中选择将使用第一个组合相关数据更新第二个组合(基于您的问题名称:

  

我有两个组合框和xml文件,我想从xml中填充组合框1中的服务器名称并基于服务器名称填充第二个组合框

)。

这是一个基于两个可观察集合及其更新机制的解决方案。  1. Xaml代码:

<Window x:Class="SimpleDataGrid.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:simpleDataGrid="clr-namespace:SimpleDataGrid"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <simpleDataGrid:GridViewModel/>
</Window.DataContext>
<Grid >
    <DataGrid x:Name="SelectDataGrid" ItemsSource="{Binding Persons}" HorizontalAlignment="Left" VerticalAlignment="Top" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridCheckBoxColumn x:Name="dgCheckBox" Header="Select" Width="45" Binding="{Binding IsChecked}"/>
            <DataGridTextColumn Header="FIRST NAME" Width="125" Binding="{Binding FNAME}"/>
            <DataGridTextColumn Header="LAST NAME" Width="125" Binding="{Binding LNAME}"/>
            <DataGridComboBoxColumn Header="Servers"
                                    DisplayMemberPath="ServerName" SelectedValueBinding="{Binding SelectedServer, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
                <DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}}, Path=DataContext.Servers}"/>
                        <Setter Property="IsReadOnly" Value="True"/>
                    </Style>
                </DataGridComboBoxColumn.ElementStyle>
                <DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}}, Path=DataContext.Servers}"/>
                    </Style>
                </DataGridComboBoxColumn.EditingElementStyle>
            </DataGridComboBoxColumn>
            <DataGridComboBoxColumn Header="Dbs" 
                                    DisplayMemberPath="DbName" 
                                    SelectedValueBinding="{Binding SelectedDb, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
                <DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}}, Path=DataContext.Dbs}"/>
                        <Setter Property="IsReadOnly" Value="True"/>
                    </Style>
                </DataGridComboBoxColumn.ElementStyle>
                <DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}}, Path=DataContext.Dbs}"/>
                    </Style>
                </DataGridComboBoxColumn.EditingElementStyle>
            </DataGridComboBoxColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid></Window>

2。主模型代码给出了解决方案。 UpdateDbCollection 方法可以调用您的GetDatabases方法,查询服务器相关数据库,将该数据放入“新数据库”中。在添加数据并重新构建数据时,使用新数据列出并更新第二个组合可观察集合。

    public class Person : BaseObservableObject
{
    private string _lName;
    private string _fName;
    private bool _checked;

    private object _selectedServer;
    private DbDetails _selectedDb;

    public Person()
    {
        Dbs = new ObservableCollection<DbDetails>();
        Servers = new ObservableCollection<ServerDetails>(new List<ServerDetails>
        {
            new ServerDetails
            {
                ServerName = "A",
                DbDetailses = new List<DbDetails>
                {
                    new DbDetails{DbName = "AA"},
                    new DbDetails{DbName = "AB"},
                    new DbDetails{DbName = "AC"},
                }
            },
             new ServerDetails
            {
                ServerName = "B",
                DbDetailses = new List<DbDetails>
                {
                    new DbDetails{DbName = "BA"},
                    new DbDetails{DbName = "BB"},
                    new DbDetails{DbName = "BC"},
                }
            },
             new ServerDetails
            {
                ServerName = "C",
                DbDetailses = new List<DbDetails>
                {
                    new DbDetails{DbName = "CA"},
                    new DbDetails{DbName = "CB"},
                }
            }
        });
    }
    public DbDetails SelectedDb
    {
        get { return _selectedDb; }
        set
        {
            _selectedDb = value;
            OnPropertyChanged();
        }
    }

    public object SelectedServer
    {
        get { return _selectedServer; }
        set
        {
            _selectedServer = value;
            OnPropertyChanged();
            UpdateDbCollection(SelectedServer as ServerDetails);
        }
    }

    private void UpdateDbCollection(ServerDetails serverDetails)
    {
        //here you can get your db details by selected server
        var newDbs = serverDetails.DbDetailses;
        newDbs.ForEach(details => Dbs.Add(details));
        var valuesToClear =
            Dbs.Where(
                existingDbDetails => newDbs.FirstOrDefault(dbDetails => existingDbDetails == dbDetails) == null).ToList();
        valuesToClear.ForEach(details => Dbs.Remove(details));
    }

    public ObservableCollection<ServerDetails> Servers { get; set; }

    public ObservableCollection<DbDetails> Dbs { get; set; }

    public bool IsChecked
    {
        get { return _checked; }
        set
        {
            _checked = value;
            OnPropertyChanged();
        }
    }

    public string LNAME
    {
        get { return _lName; }
        set
        {
            _lName = value;
            OnPropertyChanged();
        }
    }

    public string FNAME
    {
        get { return _fName; }
        set
        {
            _fName = value;
            OnPropertyChanged();
        }
    }
}                                                

3。型号:

    public class ServerDetails:BaseObservableObject
{
    private string _serverName;

    public string ServerName
    {
        get { return _serverName; }
        set
        {
            _serverName = value;
            OnPropertyChanged();
        }
    }

    public List<DbDetails> DbDetailses { get; set; }
}

public class DbDetails:BaseObservableObject
{
    private string _dbName;

    public string DbName
    {
        get { return _dbName; }
        set
        {
            _dbName = value;
            OnPropertyChanged();
        }
    }
}
  1. 查看型号代码:

    公共类GridViewModel:BaseObservableObject {

    public GridViewModel()
    {
        var l = new List<Person>
        {
            new Person {FNAME = "John", LNAME = "W"},
            new Person {FNAME = "George", LNAME = "R"},
            new Person {FNAME = "Jimmy", LNAME = "B"},
            new Person {FNAME = "Marry", LNAME = "B"},
            new Person {FNAME = "Ayalot", LNAME = "A"},
        };
        Persons = new ObservableCollection<Person>(l);
    }
    
    public ObservableCollection<Person> Persons { get; set; }
    

    }

  2. BaseObservableObject是INotifyPropertyChanged的简单实现。

  3. 我希望它会对你有所帮助。 谢谢你,