亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

WPF 將數據綁定到 DataGrid 的 TabControl

WPF 將數據綁定到 DataGrid 的 TabControl

C#
倚天杖 2023-07-22 17:00:44
我正在嘗試創建一個 UI,其中有一個 TabControl,并且每個選項卡中都有一個 DataGrid。我想動態添加/刪除選項卡以及 DataGrid 的行/列。這是代碼示例:Test.xaml<StackPanel>        <Button x:Name="Button" Content="Add tab" Click="Button_Click"/>        <Controls:MetroAnimatedTabControl x:Name="TabControl"                                          TabStripPlacement="Left"                                           DisplayMemberPath="TabName">                <TabControl.ContentTemplate>                    <DataTemplate>                        <DataGrid  AutoGenerateColumns="True" DataContext="{Binding Context}" />                    </DataTemplate>                </TabControl.ContentTemplate>        </Controls:MetroAnimatedTabControl></StackPanel>以及隱藏的代碼Test.xaml.cspublic class Tab{    public string TabName { get; set; }    public DataTable Content { get; set; }    public Tab(string name, DataTable content)    {        TabName = name;        Content = content;    }    public Tab(string name, List<string[]> content)    {        Content = new DataTable();        foreach (var item in content){            Content.Columns.Add(item[0], typeof(string));        }        DataRow row = Content.NewRow();        foreach (var item in content)        {            row[item[0]] = item[1];        }        Content.Rows.Add(row);        TabName = name;    }}它可以編譯,但是當您運行該應用程序時,窗口中沒有顯示任何內容。數據綁定很可能是錯誤的(尤其是 DataGrid,因為我不知道如何使用像我這樣的類來做到這一點)。如果代碼中不清楚,在我的Tab類中,我有TabName選項卡名稱的屬性,并且ContentDataTable 應該是相應 DataGrid 中的數據源。我想以某種方式將它們綁定到 xaml,如果實例被修改,UI 也會更新。是否可以這樣做,或者我需要采取不同的方法?
查看完整描述

2 回答

?
溫溫醬

TA貢獻1752條經驗 獲得超4個贊

DataContext當前作用域中綁定的上下文。是TabControl一個ItemsControl,它有一個ItemsSource需要一個IEnumerableIEnumerable<Tab>在本例中)。您應該引入一個視圖模型,它充當 the?DataContext,在本例中公開the綁定到的UserControl源集合。視圖模型通常將托管視圖可以綁定到的所有數據。視圖模型通常實現接口,以便 UI 控件在綁定源更改時自動更新。ObservableCollection<Tab>TabControlINotifyPropertyChanged

Tab.cs(選項卡控件將綁定到的數據模型):

public class Tab

{

? ? public string TabName { get; set; }

? ? public DataTable Content { get; set; }


? ? public Tab(string name, DataTable content)

? ? {

? ? ? ? TabName = name;

? ? ? ? Content = content;

? ? }


? ? public Tab(string name, List<string[]> content)

? ? {


? ? ? ? Content = new DataTable();

? ? ? ? foreach (var item in content){

? ? ? ? ? ? Content.Columns.Add(item[0], typeof(string));

? ? ? ? }

? ? ? ? DataRow row = Content.NewRow();

? ? ? ? foreach (var item in content)

? ? ? ? {

? ? ? ? ? ? row[item[0]] = item[1];

? ? ? ? }

? ? ? ? Content.Rows.Add(row);

? ? ? ? TabName = name;

? ? }

}

ViewModel.cs(DataContext將集合UserControl公開Tab為綁定上下文的):


class ViewModel : INotifyPropertyChanged

{

? public ViewModel()

? {

? ? this.ClsTabs = new ObservableCollection<Tab>();


? ? ClsTabs.Add(new Tab("Animals", new List<string[]>() { new string[] { "Name", "Tiger" }, new string[] { "Tail", "Yes" } }));

? ? ClsTabs.Add(new Tab("Vegetables", new List<string[]>() { new string[] { "Name", "Tomato" }, new string[] { "Color", "Red" }, new string[] { "Taste", "Good" } }));

? ? ClsTabs.Add(new Tab("Cars", new List<string[]>() { new string[] { "Name", "Tesla" } }));

? }


? private ObservableCollection<Tab> clsTabs;


? public ObservableCollection<Tab> ClsTabs

? {

? ? get => this.clsTabs;

? ? set

? ? {

? ? ? if (Equals(value, this.clsTabs)) return;

? ? ? this.clsTabs = value;

? ? ? OnPropertyChanged();

? ? }

? }


? public event PropertyChangedEventHandler PropertyChanged;


? protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)

? {

? ? this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

? }

}

測試.xaml.cs:


public partial class Test: UserControl

{

? ? public Test()

? ? {

? ? ? ? InitializeComponent();

? ? }


? ? private void Button_Click(object sender, RoutedEventArgs e)

? ? {

? ? ? ? (this.DataContext as ViewModel)?.ClsTabs.Add(new Tab("New", new List<string[]>() { new string[] { "Name", "Something" }, new string[] { "Detail", "No" } }));

? ? }

}

測試.xaml


<UserControl x:Class="WpfTestRange.Main.Test">


? <!-- Set the DataContext of the Test control to an instance of ViewModel -->

? <UserControl.DataContext>

? ? <local:ViewModel />

? </UserControl.DataContext>


? <Grid>

? ? <StackPanel>

? ? ? <Button x:Name="Button"

? ? ? ? ? ? ? Content="Add tab"

? ? ? ? ? ? ? Click="Button_Click" />


? ? ? <MetroAnimatedTabControl x:Name="TabControl"?

? ? ? ? ? ? ? ? ? ItemsSource="{Binding ClsTabs}"

? ? ? ? ? ? ? ? ? TabStripPlacement="Left"

? ? ? ? ? ? ? ? ? DisplayMemberPath="TabName">

? ? ? ? <TabControl.ContentTemplate>

? ? ? ? ? <DataTemplate DataType="local:Tab">

? ? ? ? ? ? <DataGrid AutoGenerateColumns="True" ItemsSource="{Binding Content}" />

? ? ? ? ? </DataTemplate>

? ? ? ? </TabControl.ContentTemplate>

? ? ? </TabControl>

? ? </StackPanel>


? </Grid>

</UserControl>


查看完整回答
反對 回復 2023-07-22
?
慕運維8079593

TA貢獻1876條經驗 獲得超5個贊

根本問題是,這些為多個項目生成內容的控件應該使用 屬性(而ItemsSource不是DataContext.

該行 TabControl.DataContext = clsTabs; 應分配給TabControl.ItemsSource

此時您將在輸出窗格中看到

System.Windows.Data 錯誤:40:BindingExpression 路徑錯誤:在“對象”“選項卡”(HashCode=55467050) 上找不到“上下文”屬性。BindingExpression:路徑=上下文;DataItem='Tab'(哈希碼=55467050);目標元素是“DataGrid”(名稱=“”);目標屬性是“DataContext”(類型“Object”)

該行 <DataGrid  AutoGenerateColumns="True" DataContext="{Binding Context}" /> 存在先前的問題錯誤的屬性名稱。應該是 <DataGrid AutoGenerateColumns="True" ItemsSource="{Binding Content}" /> 這樣,然后你就應該很好。


查看完整回答
反對 回復 2023-07-22
  • 2 回答
  • 0 關注
  • 502 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號