【问题标题】:Cannot get selected ComboBox items in MainWindow.xaml.cs无法在 MainWindow.xaml.cs 中获取选定的 ComboBox 项
【发布时间】:2019-08-24 00:03:51
【问题描述】:

我想访问 MainWindow.xaml.cs 中的 ComboBox 项(在另一个类中定义),但我不能。

我是 C# 和 WPF 的新手。此代码的目的是获取选定的 ComboBox 项作为搜索键。我从互联网上的许多示例代码中复制了出来,现在我完全迷路了。我什至不知道哪一部分是错的。所以,让我展示整个代码(对不起):

MainWindow.xaml:

<Window x:Class="XY.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:XY"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="454.4">
<Grid>
    <DataGrid ItemsSource="{Binding channels}"
        SelectedItem="{Binding SelectedRow, Mode=TwoWay}"
              Margin="0,0,0,-0.2">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding name}"
                                Header="Channel" Width="Auto"/>
            <DataGridTemplateColumn Width="100" Header="Point Setting">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox x:Name="piontsComboBox"
                                  ItemsSource="{Binding DataContext.points,
                            RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                                  SelectionChanged="PrintText"
                                  DisplayMemberPath="name" 
                                  SelectedValuePath="name"
                                  Margin="5"
                                  SelectedItem="{Binding DataContext.SelectedPoint,
                            RelativeSource={RelativeSource AncestorType={x:Type Window}},
                            Mode=TwoWay}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
    <TextBox x:Name="tb" Width="140" Height="30" Margin="10,250,200,30"></TextBox>
    <Button x:Name="Browse_Button" Content="Browse" Margin="169,255,129.6,0"
                Width="75" Click="Browse_Button_Click" Height="30" VerticalAlignment="Top"/>
</Grid>

MainWindow.xaml.cs:

    using System;
    using System.Windows;
    using System.Windows.Controls;

    namespace XY
    {
        public partial class MainWindow : Window
        {
            public GridModel gridModel { get; set; }
            public MainWindow()
            {
                InitializeComponent();
                gridModel = new GridModel();
                this.DataContext = gridModel;
            }

        private void Browse_Button_Click(object sender, RoutedEventArgs e)
        {
            WakeupClass clsWakeup = new WakeupClass();
            clsWakeup.BrowseFile += new EventHandler(gridModel.ExcelFileOpen);
            clsWakeup.Start();
        }

        void PrintText(object sender, SelectionChangedEventArgs args)
        {
            //var item = pointsComboBox SelectedItem as Point;
            //if(item != null)
            //{
            //    tb.Text = "You selected " + item.name + ".";
            //}
            MessageBox.Show("I'd like to show the item.name in the TextBox.");
        }
    }

    public class WakeupClass
    {
        public event EventHandler BrowseFile;
        public void Start()
        {
            BrowseFile(this, EventArgs.Empty);
        }
    }
}

Point.cs:

namespace XY
{

    public class Point : ViewModelBase
    {
        private string _name;
        public string name
        {
            get { return _name; }
            set
            {
                _name = value;
                OnPropertyChanged("name");
            }
        }

        private int _code;
        public int code
        {
            get { return _code; }
            set
            {
                _code = value;
                OnPropertyChanged("code");
            }
        }
    }
}

记录.cs:

    namespace XY
{
    public class Record : ViewModelBase
{
    private string _name;
    public string name
    {
        get { return _name; }
        set
        {
            _name = value;
            OnPropertyChanged("name");
        }
    }

    private int _PointCode;

        public int PointCode
        {
            get { return _PointCode; }
            set
            {
                _PointCode = value;
                OnPropertyChanged("PointCode");
            }
        }

        private Record _selectedRow;
        public Record selectedRow
        {
            get { return _selectedRow; }
            set
            {
                _selectedRow = value;
                OnPropertyChanged("SelectedRow");
            }
        }

        private Point _selectedPoint;
        public Point SelectedPoint
        {
            get { return _selectedPoint; }
            set
            {
                _selectedPoint = value;
                _selectedRow.PointCode = _selectedPoint.code;
                OnPropertyChanged("SelectedRow");
            }
        }
    }
}

ViewModelBase.cs:

    using System.ComponentModel;

namespace XY
{
    public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    }
}

GridModel.cs:

using System.Collections.ObjectModel;
using System.Windows;

namespace XY
{
    public class GridModel : ViewModelBase
    {
        public ObservableCollection<Record> channels { get; set; }
        public ObservableCollection<Point> points { get; set; }
        public GridModel()
        {
            channels = new ObservableCollection<Record>() {
                new Record {name = "High"},
                new Record {name = "Middle"},
                new Record {name = "Low"}
            };
        }

        internal void ExcelFileOpen(object sender, System.EventArgs e)
        {
            points = new ObservableCollection<Point> { new Point { } };
            points.Add(new Point { name = "point1", code = 1 });
            points.Add(new Point { name = "point2", code = 2 });
            points.Add(new Point { name = "point3", code = 3 });
            MessageBox.Show("Assume that Excel data are loaded here.");
        }
    }
}

流程如下:

  1. 点击“浏览”按钮加载数据。

  2. 点击第一列“频道”对列表进行排序(这是一个错误,但如果不这样做,“点设置”项将不会显示)。

    李>
  3. 点击“点设置”组合框选择项目(点1、点2、...等)。

此代码应该在 TextBox 中显示所选项目的名称。

如果所有内容都在 MainWindow.xaml.cs 中,则可以访问 ComboBox 项。由于我将代码分成不同的类,它一直没有工作。请帮我。任何建议都会有所帮助。

【问题讨论】:

    标签: c# wpf data-binding combobox viewmodel


    【解决方案1】:

    您的绑定确实有效。您可以利用sender 对象来实现您想要的。

    void PrintText(object sender, SelectionChangedEventArgs args)
    {
        var comboBox = sender as ComboBox;
        var selectedPoint = comboBox.SelectedItem as Point;
        tb.Text = selectedPoint.name;
    }
    

    【讨论】:

      【解决方案2】:

      问题在于 DataGridColumn 不是 WPF 逻辑树的一部分,因此您的相对源绑定将不起作用。让您的绑定工作的唯一方法是一种 kluge(根据我的经验,在 WPF 中很常见)。在逻辑树中创建一个虚拟元素,然后引用它。

      所以

      <FrameworkElement x:Name="dummyElement" Visibility="Collapsed"/>
      <DataGrid ItemsSource="{Binding channels}"
          SelectedItem="{Binding SelectedRow, Mode=TwoWay}"
                Margin="0,0,0,-0.2">
      

      那么您的绑定将如下所示

      <ComboBox x:Name="piontsComboBox"
                                    ItemsSource="{Binding DataContext.points,
                              Source={x:Reference dummyElement}}"
                                    SelectionChanged="PrintText"
                                    DisplayMemberPath="name" 
                                    SelectedValuePath="name"
                                    Margin="5"
                                    SelectedItem="{Binding DataContext.SelectedPoint,
                              Source={x:Reference dummyElement},
                              Mode=TwoWay}"/>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-05
        • 1970-01-01
        • 1970-01-01
        • 2020-05-17
        • 1970-01-01
        • 2018-09-08
        相关资源
        最近更新 更多