简体   繁体   English

清除数据绑定的comboBox上的数据

[英]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.ResourcesPage.Resources切换,在UWP中,您可以使用x:Bind并使用x:Bind可以帮助您摆脱RelativeResource=self

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM