簡體   English   中英

在 WPF 中的 XAML 中設置 DataContext

[英]Setting DataContext in XAML in WPF

我有以下代碼:

主窗口.xaml

<Window x:Class="SampleApplication.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"
        DataContext="{Binding Employee}">
    <Grid>       
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="200" />
        </Grid.ColumnDefinitions>

        <Label Grid.Row="0" Grid.Column="0" Content="ID:"/>
        <Label Grid.Row="1" Grid.Column="0" Content="Name:"/>
        <TextBox Grid.Column="1" Grid.Row="0" Margin="3" Text="{Binding EmpID}" />
        <TextBox Grid.Column="1" Grid.Row="1" Margin="3" Text="{Binding EmpName}" /> 
    </Grid>
</Window>

員工.cs

namespace SampleApplication
{
    public class Employee
    {
        public Employee()
        {
            EmployeeDetails employeeDetails = new EmployeeDetails();
            employeeDetails.EmpID = 123;
            employeeDetails.EmpName = "ABC";
        }
    }

    public class EmployeeDetails
    {
        private int empID;
        public int EmpID
        {
            get
            {
                return empID;
            }
            set
            {
                empID = value;
            }
        }

        private string empName;
        public string EmpName
        {
            get
            {
                return empName;
            }
            set
            {
                empName = value;
            }
        }
    }
}

這是非常簡單的代碼,我只想將 Employee.cs 類中的EmpIDEmpName屬性綁定到 MainWindow.xaml 中文本框的文本屬性,但是當我運行代碼時,這些文本框中沒有任何內容。 綁定對嗎?

此代碼將始終失敗。

正如所寫,它說:“在我的 DataContext 屬性上查找名為“Employee”的屬性,並將其設置為 DataContext 屬性”。 顯然這是不對的。

為了讓您的代碼正常工作,請將您的窗口聲明更改為:

<Window x:Class="SampleApplication.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SampleApplication"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
   <local:Employee/>
</Window.DataContext>

這將聲明一個新的 XAML 命名空間(本地)並將 DataContext 設置為 Employee 類的實例。 這將導致您的綁定顯示默認數據(來自您的構造函數)。

但是,這實際上不太可能是您想要的。 相反,您應該有一個帶有Employee屬性的新類(稱為 MainViewModel),然后綁定到該類,如下所示:

public class MainViewModel
{
   public Employee MyEmployee { get; set; } //In reality this should utilize INotifyPropertyChanged!
}

現在您的 XAML 變為:

<Window x:Class="SampleApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SampleApplication"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
       <local:MainViewModel/>
    </Window.DataContext>
    ...
    <TextBox Grid.Column="1" Grid.Row="0" Margin="3" Text="{Binding MyEmployee.EmpID}" />
    <TextBox Grid.Column="1" Grid.Row="1" Margin="3" Text="{Binding MyEmployee.EmpName}" />

現在您可以添加其他屬性(其他類型、名稱)等。有關更多信息,請參閱實現模型-視圖-視圖模型模式

首先,您應該在Employee類中創建包含員工詳細信息的屬性:

public class Employee
{
    public Employee()
    {
        EmployeeDetails = new EmployeeDetails();
        EmployeeDetails.EmpID = 123;
        EmployeeDetails.EmpName = "ABC";
    }

    public EmployeeDetails EmployeeDetails { get; set; }
}

如果您不這樣做,您將在Employee構造函數中創建對象的實例,並且您將失去對它的引用。

在 XAML 中,您應該創建Employee類的實例,然后您可以將其分配給DataContext

您的 XAML 應如下所示:

<Window x:Class="SampleApplication.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"
    xmlns:local="clr-namespace:SampleApplication"
   >
    <Window.Resources>
        <local:Employee x:Key="Employee" />
    </Window.Resources>
    <Grid DataContext="{StaticResource Employee}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="200" />
        </Grid.ColumnDefinitions>

        <Label Grid.Row="0" Grid.Column="0" Content="ID:"/>
        <Label Grid.Row="1" Grid.Column="0" Content="Name:"/>
        <TextBox Grid.Column="1" Grid.Row="0" Margin="3" Text="{Binding EmployeeDetails.EmpID}" />
        <TextBox Grid.Column="1" Grid.Row="1" Margin="3" Text="{Binding EmployeeDetails.EmpName}" />
    </Grid>
</Window>

現在,在使用員工詳細信息創建屬性后,您應該使用此屬性進行綁定:

Text="{Binding EmployeeDetails.EmpID}"

這里有幾個問題。

  1. 您不能將 DataContext 分配為DataContext="{Binding Employee}"因為它是一個不能分配為字符串的復雜對象。 所以你必須使用<Window.DataContext></Window.DataContext>語法。
  2. 您將表示數據上下文對象的類分配給視圖,而不是單個屬性,因此{Binding Employee}在這里無效,您只需要指定一個對象。
  3. 現在,當您使用如下有效語法分配數據上下文時
 <Window.DataContext> <local:Employee/> </Window.DataContext>

知道您正在創建Employee 類的新實例並將其分配為數據上下文對象。 您可能在默認構造函數中沒有任何內容,因此不會顯示任何內容。 但是你如何在代碼隱藏文件中管理它? 您已經對 DataContext 進行了類型轉換。

    private void my_button_Click(object sender, RoutedEventArgs e)
    {
        Employee e = (Employee) DataContext;
    }
  1. 第二種方法是在文件本身的代碼背后分配數據上下文。 優點是您的文件背后的代碼已經知道它並且可以使用它。

     public partial class MainWindow : Window { Employee employee = new Employee(); public MainWindow() { InitializeComponent(); DataContext = employee; } }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM