[英]Clearing data on a comboBox that's data bound
I need help with this part of my code. 我需要这部分代码的帮助。 I'm trying to do 2 things here:
我正在尝试在这里做两件事:
1st, I need my comboBox cmbTechSearch filled with a list of names retrieved from a SQL database. 首先,我需要在comboBox cmbTechSearch中填充从SQL数据库检索的名称列表。 Those names belong to an object called Tecnico.
这些名称属于一个称为Tecnico的对象。 So far, so good.
到现在为止还挺好。 But if I click on the comboBox twice, I get the names duplicated... And so on.
但是,如果我单击comboBox两次,我将得到重复的名称...依此类推。 Adding cmbTechSearch.Items.Clear();
添加cmbTechSearch.Items.Clear(); didn't solve it because the box was data binded, firing an error message.
没有解决该问题,因为该盒子已绑定数据,并发出错误消息。 So I added cmbTechSearch.DataSource = null;
所以我添加了cmbTechSearch.DataSource = null; which solved the error message but didn't clear my box.
解决了错误消息,但没有清除我的盒子。 Nor did cmbTechSearch.ResetText();
cmbTechSearch.ResetText()也没有; Right now I'm unsure about how to clear it so that data doesn't come duplicated if I click the box again.
现在,我不确定如何清除它,以便再次单击该框时不会重复数据。
2nd, that list retrieved from SQL database brings more than just the name attached. 第二,从SQL数据库检索的列表不仅带来附加的名称。 It brings an e-mail for each object too.
它还为每个对象带来一封电子邮件。 And I can't figure out how to retrieve the mail associated to the chosen name on that comboBox.
而且我不知道如何在该comboBox上检索与所选名称关联的邮件。 Mind you, email is a global string var since I use it in other methods within the code.
请注意,电子邮件是全局字符串var,因为我在代码内的其他方法中使用了它。 That part is commented because it doesn't work.
该部分已被注释,因为它不起作用。
public void TechSearch_loaded(object sender, EventArgs e) 公共无效TechSearch_loaded(对象发送者,EventArgs e)
{ {
//all these 3 entries are supposedly to clear the comboBox cmbTechSearch; //所有这3个条目都应该清除comboBox cmbTechSearch; all of them fail but if I remove the 1st line I get an error saying that there's already some data bound to the box (but only if I click a 2nd time)
它们都失败了,但是如果我删除第一行,我会收到一条错误消息,说盒子已经绑定了一些数据(但仅当我单击第二次时)
cmbTechSearch.DataSource = null;
cmbTechSearch.Items.Clear();
cmbTechSearch.ResetText();
//there's a class called Tecnico and all the info about that object is saved on a SQL db. //有一个名为Tecnico的类,有关该对象的所有信息都保存在SQL数据库中。 This part populates a list of Tecnicos with info from the db.
此部分使用数据库中的信息填充Tecnicos列表。
List<Tecnico> tecnicos = new List<Tecnico>();
tecnicos = bd.ProcuraPerfisTipo("TEC");
//then I get a list of Tecnicos and retrieve one attribute (Nome) for each tecnico in the list //然后我得到一个Tecnicos列表,并为列表中的每个tecnico检索一个属性(Nome)
List<String> TechSearch = new List<String>();
foreach (Tecnico obj in tecnicos)
{
TechSearch.Add(obj.Nome);
}
//lastly I populate the comboBox with the info I got from the list. //最后,我使用从列表中获得的信息填充comboBox。
cmbTechSearch.DataSource = TechSearch;
//email = cmbTechSearch.ToString();
}
There's a class named Tecnico, another named BDTicketSQL and another named iBDTicketSQL (the first calling the SQL db and running updates, queries and inserts while the second is used for interface). 有一个名为Tecnico的类,另一个名为BDTicketSQL和另一个名为iBDTicketSQL的类(第一个调用SQL db并运行更新,查询和插入,第二个用作接口)。 Those classes are all external to this form.
这些类都在此表单的外部。 I just get date from them to populate the form with whatever info I need.
我只是从他们那里得到日期,以便用我需要的任何信息填充表格。
Alright, so what you need to reduce your effort is DataBinding
. 好的,因此您需要减少工作量的是
DataBinding
。 Since you've mentioned databinding in your question, I am going to assume you know it. 既然您在问题中提到了数据绑定,那么我将假设您知道它。 So I'll quickly run through the answer.
因此,我将快速浏览答案。 Also since you hadn't mentioned any platform, I assumed it to be
WPF
but the code can be copied to WinRT or UWP if you want. 同样,因为您没有提到任何平台,所以我假设它是
WPF
但是如果需要,可以将代码复制到WinRT或UWP。 Just incase it's a different platform, do let me know in the comments section Link to full solution In case you wana skip 万一这是一个不同的平台,请在评论部分让我知道。 链接到完整的解决方案,以防您跳过
Your XAML: I've used basic binding to codebehind to avoid a lot of classes for a sample. 您的XAML:我对代码隐藏使用了基本绑定,以避免为示例创建大量类。 below is the code:
下面是代码:
<StackPanel Margin="20">
<ComboBox x:Name="UserCombobox"
Height="20"
Width="300"
ItemsSource="{Binding DataFromSQLService,Mode=OneWay}"
SelectedItem="{Binding CurrentSelectedUser,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
ItemTemplate="{StaticResource UserDataTemplate}"
SelectionChanged="UserCombobox_SelectionChanged"/>
<Button Content="Clear Combo" Height="30" Width="100" Margin="10" Click="ClearData"/>
<Button Content="Load Combo" Height="30" Width="100" Margin="10" Click="LoadData"/>
<TextBlock Text="{Binding CurrentSelectedUser.Name,Mode=OneWay}" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding CurrentSelectedUser.Email,Mode=OneWay}" HorizontalAlignment="Center"/>
</StackPanel>
Now, your Window.Resources
where you put your dataTemplate
for your combobox Items. 现在,您的
Window.Resources
将您的dataTemplate
放置在组合框项目的位置。
<Window.Resources>
<DataTemplate x:Key="UserDataTemplate">
<StackPanel>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
Now, self bind the view to it's codebehind, so in the Window Declaration add 现在,将视图自身绑定到其背后的代码,因此在“窗口声明”中添加
DataContext = "{Binding RelativeSource={RelativeSource Self}}"
Now that the view is ready, let's quickly get our code behind ready. 现在视图已经准备好,让我们快速准备好代码。
A Dummy User Class you can replace this with your model class. 虚拟用户类,您可以将其替换为模型类。
public class MyDummyUser
{
public MyDummyUser(string name, string email)
{
Name = name;
Email = email;
}
public string Name { get; set; }
public string Email { get; set; }
}
Now Create a quick property to hold your currently selected user. 现在,创建一个快速属性来保存您当前选择的用户。
private MyDummyUser currentSelectedUser;
public MyDummyUser CurrentSelectedUser
{
get { return currentSelectedUser; }
set { currentSelectedUser = value; RaisePropertyChanged(nameof(CurrentSelectedUser)); }
}
Now create an observable collection to hold your data from the SQL service: 现在创建一个可观察的集合来保存来自SQL服务的数据:
private ObservableCollection<MyDummyUser> dataFromSQLService;
public ObservableCollection<MyDummyUser> DataFromSQLService
{
get { return dataFromSQLService; }
set { dataFromSQLService = value; RaisePropertyChanged(nameof(DataFromSQLService)); }
}
Now Implement INotifyPropertyChanged
现在实现
INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
//if using c# 6.0 or later replace the above with
//public void RaisePropertyChanged(string propertyName)=>
// PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
Now Add a listener to the combobox.SelectionChanged
event so that you know when the selected user changed: 现在,将一个侦听器添加到
combobox.SelectionChanged
事件,以便您知道所选用户何时更改:
private void UserCombobox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
if (CurrentSelectedUser != null && !string.IsNullOrEmpty(CurrentSelectedUser?.Email?.Trim()))
{
//perform what you wana do with the email.
}
}
Create Two methods: LoadData and ClearData. 创建两个方法:LoadData和ClearData。
private void ClearData(object sender, RoutedEventArgs e)
{
DataFromSQLService = null;
}
private void LoadData(object sender, RoutedEventArgs e)
{
List<MyDummyUser> someData = new List<MyDummyUser>()
{
new MyDummyUser("User 1","User1@gmail.com"),
new MyDummyUser("User 2","User2@gmail.com"),
new MyDummyUser("User 3","User3@gmail.com"),
new MyDummyUser("User 4","User4@gmail.com"),
new MyDummyUser("User 5","User5@gmail.com"),
new MyDummyUser("User 6","User6@gmail.com"),
};
DataFromSQLService = new ObservableCollection<MyDummyUser>(someData);
}
Please Note I've used an example of a WPF
but even if you want to use the code for WinRT or UWP it'll work, just remember to switch Window.Resources
with Page.Resources
also, in UWP you can use x:Bind
and using x:Bind can help you get rid of the RelativeResource=self
请注意,我已经使用了
WPF
的示例,但是即使您想使用WinRT或UWP的代码也可以使用,也请记住只将Window.Resources
与Page.Resources
切换,在UWP中,您可以使用x:Bind
并使用x:Bind可以帮助您摆脱RelativeResource=self
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.