XAML 如何在WPF中访问DataGrid中Combobox的属性

dffbzjpn  于 2022-12-07  发布在  其他
关注(0)|答案(2)|浏览(173)

我想在DataGrid中的DataGridTemplateColumn内显示ComboBox中的数据,但它在绑定中为空,因此我决定在代码后面填充它,但我无法通过名称访问它!

XAML

<Window x:Class="ComboDataWPF.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:ComboDataWPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" WindowStartupLocation="CenterScreen" Loaded="Window_Loaded">
    
    <Grid>
        <DataGrid x:Name="MainDataGrid" AutoGenerateColumns="False" ItemsSource="{Binding ALLMYDATA, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}">

            <DataGrid.Columns>
                <DataGridTextColumn Header="The Name :" Width="120" Binding="{Binding NAMES, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />

                <DataGridTemplateColumn Header=" Name and Code " Width="150">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox x:Name="ComboBox1"
                                      ItemsSource="{Binding ALLMYDATA, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
                                      SelectedValuePath="{Binding CODE, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
                                      DisplayMemberPath="{Binding NAMES, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
                                      IsTextSearchEnabled="True"
                                      IsEditable="True"
                                      SelectedIndex="0"  BorderBrush="#FFADEEB4" Background="{x:Null}" BorderThickness="1">
                                
                                <ComboBox.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <VirtualizingStackPanel VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling"/>
                                    </ItemsPanelTemplate>
                                </ComboBox.ItemsPanel>
                            </ComboBox>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>

        </DataGrid>
    </Grid>
</Window>

代码隐藏

using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace ComboDataWPF
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            MyerEntities dbms = new MyerEntities();
            public ObservableCollection<MyCustomModel> ALLMYDATA { get; set; } = new ObservableCollection<MyCustomModel>();
            public class MyCustomModel
            {
                public int CODE { get; set; }
                public string NAMES { get; set; }
            }
            public MainWindow()
            {
                InitializeComponent();
                DataContext = this;
            }
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                ALLMYDATA.Clear();
                var RST = dbms.Database.SqlQuery<MyCustomModel>("SELECT CODE,NAMES FROM TCOD_ANBAR").ToList();
                foreach (var item in RST)
                {
                    ALLMYDATA.Add(item);
                }
            }
        }
    }

我的源代码:https://ufile.io/zvfoj4we
注意:我甚至试图切换到GridView,但它比Datagrid更难。
那么为什么ComboBox是空的,我如何访问C#中的ItemsSource和...之类的属性?
请指引我

pieyvz9o

pieyvz9o1#

我下载了你的源项目。并填充了2个对象的ALLMYDATA集合(因为我没有它的数据库)。

private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        ALLMYDATA.Clear();
        MyCustomModel myCustom = new MyCustomModel()
        {
            CODE = 20,
            NAMES = "Yes"
        };
        MyCustomModel myCustom2 = new MyCustomModel()
        {
            CODE = 30,
            NAMES = "No"
        };

        ALLMYDATA.Add(myCustom);
        ALLMYDATA.Add(myCustom2);
    }

因此,我看到的主要问题是在XAML中。当您将DataGridItemsSource属性设置为ALLMYDATA集合时,对于DataGrid的所有子元素,它都是DataContext,而当您尝试将ComboBoxItemsSource绑定到

ItemsSource="{Binding ALLMYDATA, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"

您会得到这个错误,因为ComboBoxDataContext是ALLMYDATA集合,而这个集合不包含ALLMYDATA属性,这就是为什么您不能在ComboBox中绑定到它的原因。

ItemsSource="{Binding ElementName=MainDataGrid, Path=ItemsSource}"

并且当ComboBoxItemsSource与现在的DataGrid相同时,它工作得很好。
其他问题与以下代码段相关:

SelectedValuePath="{Binding CODE, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
DisplayMemberPath="{Binding NAMES, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"

由于您的ComboBoxItemsSource是ALLMYDATA,现在您不需要绑定任何内容,只需编写

SelectedValuePath="CODE"
DisplayMemberPath="NAMES"

现在您的ComboBox不是空的:

以下是DataGrid的完整XAML

<DataGrid x:Name="MainDataGrid" AutoGenerateColumns="False" ItemsSource="{Binding ALLMYDATA, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}">

        <DataGrid.Columns>
            <DataGridTextColumn Header="The Name :" Width="120" Binding="{Binding NAMES, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />

            <DataGridTemplateColumn Header=" Name and Code " Width="150">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox x:Name="ComboBox1"
                                  ItemsSource="{Binding ElementName=MainDataGrid, Path=ItemsSource}"
                                  SelectedValuePath="CODE"
                                  DisplayMemberPath="NAMES"
                                  IsTextSearchEnabled="True"
                                  IsEditable="True"
                                  SelectedIndex="0"  BorderBrush="#FFADEEB4" Background="{x:Null}" BorderThickness="1">
                            
                            <ComboBox.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <VirtualizingStackPanel VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling"/>
                                </ItemsPanelTemplate>
                            </ComboBox.ItemsPanel>
                        </ComboBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
    </DataGrid>
r6vfmomb

r6vfmomb2#

你可以这样做。
首先,将您命名为Window

<Window
    :
    x:Name="ThisWindow">

然后使用Window的名称绑定ComboBoxItemsSource。还可以查看SelectedValuePathDisplayMemberPath

<ComboBox
    x:Name="ComboBox1"
    ItemsSource="{Binding ElementName=ThisWindow, Path=ALLMYDATA, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
    SelectedValuePath="CODE"
    DisplayMemberPath="NAMES"
    IsTextSearchEnabled="True"
    IsEditable="True"
    SelectedIndex="0"
    BorderBrush="#FFADEEB4"
    Background="{x:Null}"
    BorderThickness="1">
    <ComboBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling"/>
        </ItemsPanelTemplate>
    </ComboBox.ItemsPanel>
</ComboBox>

相关问题