【问题标题】:Filtering a combobox by value member of the other combobox按另一个组合框的值成员过滤组合框
【发布时间】:2015-10-04 03:31:41
【问题描述】:

我有 2 个组合框,我正在用 Linq 填充它们。

第一个是名为“City selection”的组合框:[Displaymember: CityName, Value: CityID(int)]

当用户从第一个组合框中选择一个值时,我想按 CityID 过滤我的第二个组合框。

第二个组合框名为“部门选择”。

这是代码,但它不起作用。最后一个代码块出现错误。

   private void cb_Bolge_MouseHover(object sender, EventArgs e)
    {
        cb_Bolge.DataSource = k.tbl_Bolges;
        cb_Bolge.DisplayMember = "Bolge_Ad";
        cb_Bolge.ValueMember = "Bolge_ID";
    }

    private void cb_Bolge_ValueMemberChanged(object sender, EventArgs e)
    {
        cb_Departman.DataSource = k.tbl_Departmans.Where(p=>p.Bolge_ID == Convert.ToInt32(cb_Bolge.ValueMember));
        cb_Departman.DisplayMember = "Departman_Ad";
        cb_Departman.ValueMember = "Departman_ID";
    }

这里是错误代码(抱歉有些默认是土耳其语):

System.FormatException was unhandled
HResult=-2146233033
Message=Giriş dizesi doğru biçimde değildi.
Source=System.Data.Linq
StackTrace:
konum:      System.Data.Linq.SqlClient.QueryConverter.VisitInvocation(InvocationExpression invoke)
   konum: System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
   konum: System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp)
   konum: System.Data.Linq.SqlClient.QueryConverter.VisitBinary(BinaryExpression b)
   konum: System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
   konum: System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp)
   konum: System.Data.Linq.SqlClient.QueryConverter.VisitWhere(Expression sequence, LambdaExpression predicate)
   konum: System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc)
   konum: System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc)
   konum: System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
   konum: System.Data.Linq.SqlClient.QueryConverter.ConvertOuter(Expression node)
   konum: System.Data.Linq.SqlClient.SqlProvider.BuildQuery(Expression query, SqlNodeAnnotations annotations)
   konum: System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)
   konum: System.Data.Linq.DataQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   konum: System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   konum: System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   konum: System.Data.Linq.Provider.BindingList.Create[T](DataContext context, IEnumerable`1 sequence)
   konum: System.Data.Linq.DataQuery`1.GetNewBindingList()
   konum: System.Data.Linq.DataQuery`1.System.ComponentModel.IListSource.GetList()
   konum: System.Windows.Forms.CurrencyManager.SetDataSource(Object dataSource)
   konum: System.Windows.Forms.CurrencyManager..ctor(Object dataSource)
   konum: System.Windows.Forms.BindingContext.EnsureListManager(Object dataSource, String dataMember)
   konum: System.Windows.Forms.ListControl.SetDataConnection(Object newDataSource, BindingMemberInfo newDisplayMember, Boolean force)
   konum: System.Windows.Forms.ListControl.set_ValueMember(String value)
   konum: TYH_Envanter.Envanter_Ekle.cb_Bolge_ValueMemberChanged(Object sender, EventArgs e) c:\Users\Arda\Documents\Visual Studio 2013\Projects\TYH Envanter\TYH Envanter\Envanter_Ekle.cs içinde: satır 59
   konum: System.Windows.Forms.ListControl.OnValueMemberChanged(EventArgs e)
   konum: System.Windows.Forms.ListControl.set_ValueMember(String value)
   konum: TYH_Envanter.Envanter_Ekle.cb_Bolge_MouseHover(Object sender, EventArgs e) c:\Users\Arda\Documents\Visual Studio 2013\Projects\TYH Envanter\TYH Envanter\Envanter_Ekle.cs içinde: satır 46
   konum: System.Windows.Forms.Control.OnMouseHover(EventArgs e)
   konum: System.Windows.Forms.Control.WmMouseHover(Message& m)
   konum: System.Windows.Forms.Control.WndProc(Message& m)
   konum: System.Windows.Forms.ComboBox.WndProc(Message& m)
   konum: System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   konum: System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   konum: System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   konum: System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   konum: System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   konum: System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   konum: System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   konum: System.Windows.Forms.Application.Run(Form mainForm)
   konum: TYH_Envanter.Program.Main() c:\Users\Arda\Documents\Visual Studio 2013\Projects\TYH Envanter\TYH Envanter\Program.cs içinde: satır 19
   konum: System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   konum: System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   konum: Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   konum: System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   konum: System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   konum: System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   konum: System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   konum: System.Threading.ThreadHelper.ThreadStart()
   InnerException: 

【问题讨论】:

  • 问题是什么?
  • 第二个事件应该是 SelectedValueChanged 或 SelectedIndexChanged 之类的?
  • 欢迎来到 Stack Overflow!你能告诉我们你收到什么错误信息吗?您可以使用问题下方的“编辑”标志将其编辑到您的帖子中。祝你好运!

标签: c# linq filter combobox


【解决方案1】:

您不能将convert 的值设置为int 内的linq expression,因为这将被转换为sql query 并且sql 没有function Convert.ToInt32。所以你需要创建一个变量并在其中保存值,然后与这个变量匹配。

编辑

您将获得cb_Bolge.ValueMember,这是name 的属性,它将是string,它永远不会转换为int。所以你需要得到SelectedValue

private void cb_Bolge_ValueMemberChanged(object sender, EventArgs e)
{
   int blogId=Convert.ToInt32(cb_Bolge.SelectedValue);
   cb_Departman.DataSource = k.tbl_Departmans.Where(p=>p.Bolge_ID == blogId);
   cb_Departman.DisplayMember = "Departman_Ad";
   cb_Departman.ValueMember = "Departman_ID";
}

【讨论】:

  • 你测试过这个吗?我在 linq 中使用 Convert.ToInt32 但没有遇到任何错误。
  • @ArdaIskender 现在检查答案。
【解决方案2】:

我认为您需要在 IEnumerable 上调用“.ToList()”,因为组合框需要一个项目列表(其长度是提前知道的,而 IEnumerable 不是这种情况)。

cb_Departman.DataSource = k.tbl_Departmans
    .Where(p=>p.Bolge_ID == Convert.ToInt32(cb_Bolge.ValueMember))
    .ToList();

【讨论】:

  • 不过,我在同一个块中得到了相同的错误代码。
【解决方案3】:

如果我理解得很好,你应该使用Binding。它更干净,配置完成后即可为您完成所有工作。

在您的 xaml 中:

<combobox name="first" ItemsSource="{Binding Cities}" SelectedItem="{Binding SelectedCity, mode=TwoWay}" />
<combobox name="second" ItemsSource="{Binding Departments}" />

然后,在您的控制器中,使用 INotifyPropertyChanged

public class CitySelector : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }


    private ObservableCollection<City> cities;
    public ObservableCollection<City> Cities
    {
        get { return cities; }
        set
        {
            if (cities != value)
            {
                cities = value;
                NotifyPropertyChanged("Cities");
            }
        }
    }

    private ObservableCollection<Department> departments;
    public ObservableCollection<Department> Departments
    {
        get { return departments; }
        set
        {
            if (departments != value)
            {
                departments = value;
                NotifyPropertyChanged("Departments");
            }
        }
    }

    private List<Department> MyDepartments;

    private City selectedCity;
    public City SelectedCity
    {
        get { return selectedCity; }
        set
        {
            if (selectedCity != value)
            {
                selectedCity = value;
                if (selectedCity == null)
                    Departments = null;
                else
                    Departments = MyDepartments.Where(x => x.CityId == selectedCity.Id).ToList();
                NotifyPropertyChanged("SelectedCity");
            }
        }
    }

    public CitySelector()
    {
        MyDepartments = new List<Department>() { new Department() { name = "Dep1", CityId = 1}, new Department() {name = "Dep2", CityId = 2}, new Department() {name = "Dep3", CityId = 3 } };
        Cities = new ObservableCollection<City>() { new City() { Id = 1, name = "City 1" }, new City() { Id = 2, name = "City 2" }, new City() { Id = 3, name = "City 3" } };

        this.DataContext = this;
    }
}

如果我错了,请随时纠正我。如果我没有遇到您的问题,请给我更多信息。

【讨论】:

    【解决方案4】:

    不要使用ValueMemberChanged 事件,而是使用SelectedValueChanged like:

    private void cb_Bolge_SelectedValueChanged(object sender, EventArgs e)
    {
        if (cb_Bolge.SelectedIndex != -1)
        {
            cb_Departman.DataSource = k.tbl_Departmans.Where(p=>p.Bolge_ID == Convert.ToInt32(cb_Bolge.SelectedValue));
            cb_Departman.DisplayMember = "Departman_Ad";
            cb_Departman.ValueMember = "Departman_ID";
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-25
      • 2013-03-10
      • 1970-01-01
      • 2013-01-23
      • 2013-06-18
      • 1970-01-01
      相关资源
      最近更新 更多