DataGridComboBoxColumn为什么就不能在Binding的时候引用其他Named Element了呢?

本文探讨了WPF中DataGrid绑定的问题,特别是在Columns集合上使用ItemsSource绑定时遇到的难题,并提供了一个有效的解决方案。

下面是代码,摘自一个简单的项目,模拟的是将数据库中的内容放到表格里面,其中有一列,“资源类型”是一个ComboBox,能够让用户进行选择。资源类型绑定在2个对象中,源数据是通过Restypes数组获得,而选中项是通过ResData的FK_RESID来指定:

 

 

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public List<ClsResType> GameData { get; set; }
        public List<ResData> Restypes { get; set; }

        public void LoadResData()
        {
            Restypes = new List<ResData>();
            Restypes.Add(new ResData() { Resid = "1", Resname = "ResName1" });
            Restypes.Add(new ResData() { Resid = "2", Resname = "ResName2" });
            Restypes.Add(new ResData() { Resid = "3", Resname = "ResName3" });
        }

        public MainWindow()
        {
            GameData = new List<ClsResType>();
            GameData.Add(new ClsResType() { Name = "GameData-1", FK_RESID = "1" });
            GameData.Add(new ClsResType() { Name = "GameData-2", FK_RESID = "2" });
            GameData.Add(new ClsResType() { Name = "GameData-3", FK_RESID = "3" });

            LoadResData();

            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            _TypeCombo.ItemsSource = Restypes;
        }
    }

    public class ClsResType
    {
        public string Name { get; set; }
        public string FK_RESID { get; set; }

    }

    public class ResData
    {
        public string Resid { get; set; }
        public string Resname { get; set; }
    }


 

        <DataGrid Name="dgrData"
                  Height="Auto"
                  Margin="2,2,12,2"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  AutoGenerateColumns="false"
                  Background="White"
                  ItemsSource="{Binding ElementName=ThisWindow,
                                        Path=GameData}">
            <DataGrid.Columns>
                <DataGridTextColumn Width="80"
                                    MinWidth="20"
                                    Binding="{Binding Name}"
                                    Header="资源Name" />
                <DataGridComboBoxColumn x:Name="_TypeCombo"
                                        Width="100"
                                        DisplayMemberPath="Resname"
                                        Header="资源类型"
                                        ItemsSource="{Binding ElementName=ThisWindow,
                                                              Path=Restypes}"
                                        SelectedValueBinding="{Binding FK_RESID}"
                                        SelectedValuePath="Resid" />
            </DataGrid.Columns>
        </DataGrid>


你可以注意到,我在窗口的Load事件中,把_TypeCombo这一列的ItemsSource通过代码绑定到了内部Restypes集合,然后在XAML中,我也设置了其ItemsSource的绑定,你可能会觉得两者重复了,但是!假如把代码去掉,整个程序就不工作了!在Debug的时候会看到会报错:

 

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Restypes; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=27237168); target property is 'ItemsSource' (type 'IEnumerable')

 

那么是什么原因导致该绑定失效呢?究其原因,是因为Columns集合只不过是DataGrid的一个属性,不存在于逻辑树和视觉树,所以任何的绑定都是无效的,比如DataContext啊,ElementName啊,Source啊。

 

具体解决方法可以参考这篇文章:

http://blogs.msdn.com/b/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx

 

 

 

Data Binding 和 View Binding 在内存占用方面存在一定差异。 View Binding 的主要功能是为布局文件中的视图提供类型安全的引用,它只会生成与视图相关的绑定类,不涉及数据绑定逻辑。因此,其内存占用相对较小且较为固定,主要取决于布局文件中视图的数量和复杂度。例如,在一个简单的布局文件中,使用 View Binding 生成的绑定类只会包含对布局中各个视图的引用,不会有额外的内存开销用于数据绑定和表达式计算等操作。 Data Binding 除了具备 View Binding 的视图引用功能外,还支持将数据绑定到视图上,它会生成更复杂的绑定类,并且在运行时需要维护数据与视图之间的绑定关系。这意味着 Data Binding 需要更多的内存来存储绑定信息、表达式解析和监听数据变化等。例如,当使用 Data Binding 绑定一个复杂的对象到多个视图时,需要额外的内存来处理对象属性的变化监听和视图更新逻辑。此外,Data Binding 中的表达式计算也会增加一定的内存开销,尤其是在表达式较为复杂的情况下。 综上所述,一般情况下 View Binding 的内存占用会小于 Data Binding,尤其是在不需要数据绑定功能的场景下,使用 View Binding 可以有效减少内存开销。 ### 代码示例 #### View Binding ```kotlin class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) // 使用 View Binding 访问视图 binding.textView.text = "Hello, View Binding!" } } ``` #### Data Binding ```kotlin class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView(this, R.layout.activity_main) // 创建数据对象 val user = User("John", "Doe") // 使用 Data Binding 绑定数据到视图 binding.user = user } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值