我创建了一个包含datagrid的WPF vb.net表单。在datagrid里面,我有两个组合框和两个文本框,一个用于文章的组合框文本框对,另一个用于服务。我应该将第一个组合绑定到List(Of article)类型的属性,将第二个绑定到List(Of service)类型,其中article是包含两个公共属性(articleId和articleName)的公共类,service是包含两个公共属性的公共类(serviseId和serviceName) )。文本框应显示文章和服务名称,组合框应显示ID。更改组合选择时,文本框文本也应更改其值。
列表(Of article)和List(Of service)应该从数据库中填充。
我怎么能这样做,我知道解决方案在我身边,但根本无法捕捉到它。有两个主要问题,绑定控件和数据库中的populatin列表。
如果我需要发布一部分代码我会这样做,请告诉我。
请帮我解决这个问题,
感谢。
答案 0 :(得分:0)
<DataGrid Name="dgrStavke" AutoGenerateColumns="False" Height="160" Width="600" HorizontalAlignment="Left" Margin="5" Grid.Row="7" Grid.ColumnSpan="4">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Artikl ID">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Name="cmbArtikli" Width="120" ItemsSource="{Binding Source={StaticResource artcls}, Path=listArtikli}" DisplayMemberPath="artiklId"></ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Naziv artikla" Binding="{Binding nazivArtikla}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
...
CODE
Imports System.Data
Imports System.Data.SqlClient
Imports System.Text
Namespace MW
Public Class artikl
Sub New(artid As Integer, nazivart As String)
' TODO: Complete member initialization
artiklId = artid
nazivArtikla = nazivart
End Sub
Public Property artiklId() As Integer
Public Property nazivArtikla() As String
End Class
Public Class frmDodavanjePaketa
Public Property listArtikli() As New List(Of artikl)
Private Sub popuniComboArtikli()
Dim sqlConn As SqlConnection = New SqlConnection(moduleGlobal.connString)
sqlConn.Open()
Dim strSql As New StringBuilder
strSql.Append("select a.artiklId, a.nazivArtikla ")
strSql.Append(" from artikli a ")
strSql.Append(" where isnull(a.aktivan, 0) = 1")
Dim sqlCom As SqlCommand = New SqlCommand(strSql.ToString, sqlConn)
Dim sqlDs As DataSet = New DataSet
Dim sqlDa As SqlDataAdapter = New SqlDataAdapter
sqlDa.SelectCommand = sqlCom
sqlDa.Fill(sqlDs)
For Each row As DataRow In sqlDs.Tables(0).Rows
Me.listArtikli.Add(New artikl(row.ItemArray(0).ToString, row.ItemArray(1).ToString))
Next
End Sub
End Class
End Namespace
答案 1 :(得分:0)
首先 - 抱歉,我对VB.Net不太熟悉,所以我的代码是用c#编写的。由于我不了解您的实际需求,我只能为您提供以下不是非常优雅的解决方案。
要将ComboBox
绑定到数据库中的项目,您需要使用StaticResource
,因为我可以看到您这样做了,但也许您定义错了,这就是为什么它不适合您。要使它工作,你需要有这样一个类:
public class artiklsList : List<artikl>
{
public artiklsList()
{
this.Add(new artikl(1, "first")); //this is dummy items, you need to do a database stuff here
this.Add(new artikl(2, "second"));
this.Add(new artikl(3, "third"));
}
}
像这样的xaml:
<Window.Resources>
<my:artiklsList x:Key="source"></my:artiklsList>
</Window.Resources>
当ComboBox
选择发生更改时,您还需要使用文本更新单元格。这不是一项简单的任务,因为使用Binding
使用ElementName
对控件执行此操作的最简单方法将无法在DataGrid
中使用。不管怎么说,我所做的还是有点hacky ......
所以,xaml并不是很复杂:
<DataGrid Name="dgrStavke" AutoGenerateColumns="False" Height="160" Width="600" HorizontalAlignment="Left" Margin="5" Grid.Row="7" Grid.ColumnSpan="4" >
<DataGrid.Columns>
<DataGridTemplateColumn Header="Artikl ID">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedIndex="{Binding selectedIndexID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Name="cmbArtikli" Width="120" DisplayMemberPath="artiklId" ItemsSource="{StaticResource source}">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Naziv artikla" Binding="{Binding nazivArtikla}"/>
</DataGrid.Columns>
</DataGrid>
SelectedIndex
和一个可怕的代码隐藏的绑定,用于更新文本单元格。要使绑定正常工作,articl
类必须实现INotifyPropertyChanged
接口。
public class artikl: INotifyPropertyChanged
{
public artikl(int artid, string nazivart)
{
artiklId = artid;
nazivArtikla = nazivart;
}
public int artiklId{get;set;}
private string _nazv;
public string nazivArtikla
{
get { return _nazv; }
set { _nazv = value; NotifyPropertyChanged("nazivArtikla"); }
}
//Here I think you may have questions
private int _index;
public int selectedIndexID
{
get
{
//To get a SelectedIndex for ComboBox in current row we look in
//listArtikli defined in a MainWindow for a articli item with a current
//item's Id and take the index of this item
artikl art = MainWindow.listArtikli.Find(el => el.artiklId == this.artiklId);
return MainWindow.listArtikli.IndexOf(art);
}
set
{
//This property is binded with SelectedIndex property of ComboBox.
//When selected index changed, we look in listArtikli and take
//here properties of item with this index.
//This will change values of item binded to the current grid row
_index = value;
this.nazivArtikla = MainWindow.listArtikli[value].nazivArtikla;
this.artiklId = MainWindow.listArtikli[value].artiklId;
NotifyPropertyChanged("selectedIndexID");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
窗口代码隐藏:
public partial class MainWindow : Window
{
public static artiklsList listArtikli = new artiklsList();
public static artiklsList gridsource = new artiklsList();
public MainWindow()
{
InitializeComponent();
dgrStavke.ItemsSource = gridsource;
}
}
除了gridsource
之外,您需要listArtikli
来填充DataGrid
的值。另外,由于selectedIndexID
中的所有代码,如果仅使用listArtikli
,则其值会损坏。因此listArtikli
包含articli
个项目,这些项目按照检索的顺序排序。并且gridsource
包含artiklId
中提到的nazivArtikla
- DataGrid
对。
希望它能帮助你一点点。