WPF 绑定源

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19803199/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 10:01:08  来源:igfitidea点击:

WPF BindingSource

c#wpfc#-4.0

提问by Tsukasa

Working on learning WPF by converting one of my applications over from WinForms What is the WPF way of doing the following

通过从 WinForms 转换我的一个应用程序来学习 WPF 执行以下操作的 WPF 方法是什么

 DataTable _current = _connections.Copy();
 BindingSource _bs = new BindingSource();
 bs.DataSource = _current;
 bs.Filter = "Client = '" + _selectedClient + "'";

After the new DataTable table is filtered down, then I would need to assign the binding source to a DataGrid.

过滤掉新的 DataTable 表后,我需要将绑定源分配给 DataGrid。

Update 2I have added the following

更新 2我添加了以下内容

 public ObservableCollection<SupportConnectionData> _supportConnections = new ObservableCollection<SupportConnectionData>();

turn the datatable given into ObservableCollection

将给定的数据表转换为 ObservableCollection

 DataTable _dt = Global.RequestSupportConnections(_token);
                _dt = Crypto.DecryptDataTable(_dt);
                ObservableCollection<SupportConnectionData> _connections = new ObservableCollection<SupportConnectionData>();

                foreach (DataRow _row in _dt.Rows)
                {
                    SupportConnectionData _supportConnection = new SupportConnectionData()
                    {
                        _client = _row["Client"].ToString(),
                        _server = _row["Server"].ToString(),
                        _user = _row["User"].ToString(),
                        _connected = _row["Connected"].ToString(),
                        _disconnected = _row["Disconnected"].ToString(),
                        _reason = _row["Reason"].ToString(),
                        _caseNumber = _row["CaseNumber"].ToString()
                    };
                    _connections.Add(_supportConnection);
                }

                //let me assign new collection to bound collection
                App.Current.Dispatcher.BeginInvoke((Action)(() => { _supportConnections = _connections; }));
                //this allows it to update changes to ui
                dgSupportConnections.Dispatcher.BeginInvoke((Action)(() => { dgSupportConnections.DataContext = _supportConnections; }));

XAML

XAML

  <DataGrid x:Name="dgSupportConnections" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch" AutoGenerateColumns="False" ItemsSource="{Binding}">
                    <DataGrid.Columns>
                        <DataGridTextColumn Header="Client" Binding="{Binding _client}"/>
                        <DataGridTextColumn Header="Server" Binding="{Binding _server}"/>
                        <DataGridTextColumn Header="User" Binding="{Binding _user}"/>
                        <DataGridTextColumn Header="Connected" Binding="{Binding _connected}"/>
                        <DataGridTextColumn Header="Disconnected" Binding="{Binding _disconnected}"/>
                        <DataGridTextColumn Header="Reason" Binding="{Binding _reason}"/>
                        <DataGridTextColumn Header="Case Number" Binding="{Binding _caseNumber}"/>
                    </DataGrid.Columns>
                </DataGrid>

回答by J King

get your database objects (or however you get them) into a collection (say MyCollection as ObservableCollection of Type) or collection view source then bind to that. IN wpf you have to work with the context of the class that the xaml view is bound to. So if the immediate context of the datagrid is the code behind then you would add this line to the datagrid to bind to the collection:

将您的数据库对象(或以任何方式获取它们)放入一个集合(比如 MyCollection 为 ObservableCollection of Type)或集合视图源,然后绑定到它。在 wpf 中,您必须使用 xaml 视图绑定到的类的上下文。因此,如果数据网格的直接上下文是后面的代码,那么您可以将此行添加到数据网格以绑定到集合:

<DataGrid ItemsSource="{Binding MyCollection}" / >

In win forms you can assign the collections to the datagirid in code, but in WPF you declare the binding in the xaml and the "WPF engine" takes care of the rest. There is a bit of a learning curve but it is really flexible and in my opinion reduces code.

在 win 表单中,您可以在代码中将集合分配给 datagirid,但在 WPF 中,您在 xaml 中声明绑定,“WPF 引擎”负责其余的工作。有一点学习曲线,但它非常灵活,在我看来减少了代码。

But this raises a larger discussion about the architecture of your application. I would suggest looking at MVVM to create a decoupling or separation of concerns between the model (your data), the view (user interface), and the ViewModel (which handles your business logic). THis will make you application more maintainable and testable.

但这引发了关于应用程序架构的更大讨论。我建议查看 MVVM 以在模型(您的数据)、视图(用户界面)和 ViewModel(处理您的业务逻辑)之间创建关注点的解耦或分离。这将使您的应用程序更易于维护和测试。

EDIT 1: EXAMPLE

编辑 1:示例

xaml of the window:

窗口的xaml:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid x:Name="MyDataGrid" AutoGenerateColumns="True" ItemsSource="{Binding MyObjectCollection}" DataContext="{Binding}"  />
    </Grid>
</Window>

Code behind of the Xaml window:

Xaml 窗口背后的代码:

using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Collections.ObjectModel;

class MainWindow
{


    public ObservableCollection<MyObject> MyObjectCollection = new ObservableCollection<MyObject>();

    public MainWindow()
    {
        // This call is required by the designer.
        InitializeComponent();

        // Add any initialization after the InitializeComponent() call.
        for (i = 1; i <= 10; i++) {
            MyObject newObject = new MyObject {
                age = i,
                name = "Full Name"
            };
            MyObjectCollection.Add(newObject);
        }


        MyDataGrid.ItemsSource = MyObjectCollection;
    }
}

public class MyObject
{
    public string name { get; set; }
    public string age { get; set; }
}

While this example works for learning, I DO NOT suggest this method for production apps. I think you need to look into MVVM, or MVC in order to have an application that is maintainable and testable.

虽然此示例适用于学习,但我不建议将此方法用于生产应用程序。我认为您需要研究 MVVM 或 MVC,以便拥有可维护和可测试的应用程序。