在XAML中设置元素的DataContext?

时间:2014-08-12 14:34:44

标签: wpf

你好我想要解决束缚问题。

XAML代码:

<Window x:Class="WPF_SandBox.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">
    <StackPanel x:Name="stackPanel">
        <TextBox x:Name="textBox_FirstName" Width="200" Margin="0,100,0,0" Text="{Binding Path=FirstName, UpdateSourceTrigger=PropertyChanged}"  />
        <TextBox x:Name="textBox_LastName" Width="200" Margin="0,10,0,0" Text="{Binding Path=LastName, UpdateSourceTrigger=PropertyChanged}" />
        <TextBlock x:Name="textBlock_FullName"  Background="LightBlue" Width="200" Margin="0,10,0,0" Text="{Binding Path=FullName, UpdateSourceTrigger=PropertyChanged}"  />
    </StackPanel>
</Window>

C#代码:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Person person = new Person { FirstName = "Matt", LastName = "Smith" };
            stackPanel.DataContext = person;

        }
    }

    public class Person : INotifyPropertyChanged
    {
        string firstName;
        string lastName;

        public string FirstName
        {
            get
            { 
                return firstName;
            }
            set
            {
                firstName = value;
                OnPropertyChanged("FirstName");
                OnPropertyChanged("FullName");
            }
        }

        public string LastName
        {
            get { return lastName; }
            set
            {
                lastName = value;
                OnPropertyChanged("LastName");
                OnPropertyChanged("FullName");
            }
        }

        public string FullName
        {
            get
            {
                return String.Format("{0}, {1}",lastName,firstName);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }
    }

启动时,会显示一个包含2个文本框和1个文本块的窗口。在窗口构造函数中,我创建了一个person实例,并将stackPanel的DataContext分配给此实例。第一个文本框绑定到Person类的FirstName属性,第二个TextBox绑定到LastName属性,最后的TextBlock只打印LastName属性,后跟FirstName属性。正如我之前所说,我在C#代码中设置了stackPanel的DataContext。如何在XAML中设置它?例如:

<StackPanel x:Name="stackPanel" DataContext="person">
        <TextBox x:Name="textBox_FirstName" Width="200" Margin="0,100,0,0" Text="{Binding Path=FirstName, UpdateSourceTrigger=PropertyChanged}"  />
        <TextBox x:Name="textBox_LastName" Width="200" Margin="0,10,0,0" Text="{Binding Path=LastName, UpdateSourceTrigger=PropertyChanged}" />
        <TextBlock x:Name="textBlock_FullName"  Background="LightBlue" Width="200" Margin="0,10,0,0" Text="{Binding Path=FullName, UpdateSourceTrigger=PropertyChanged}"  />
    </StackPanel>

这不起作用,但正如您所看到的,我正在尝试在XAML中设置stackPanel的DataContext,我该怎么做?

谢谢!

3 个答案:

答案 0 :(得分:3)

This brief article解释了设置DataContext的两种方式:通过XAML或通过代码。这是代码:

public class HelloWorldDataContextModel
{
    public string HelloWorld { get; set; }

    public HelloWorldDataContextModel()
    {
        HelloWorld = "Hello world!";   
    }
}

和XAML:

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

    <Window.Resources>
        <local:HelloWorldDataContextModel x:Key="HelloWorldDataContext" />   
    </Window.Resources>    

    <Grid DataContext="{StaticResource HelloWorldDataContext}">        
        <TextBox HorizontalAlignment="Left" Height="23" Margin="222,127,0,0" TextWrapping="Wrap" Text="{Binding HelloWorld}" VerticalAlignment="Top" Width="120"/>    
    </Grid>
</Window>

答案 1 :(得分:1)

我不知道你为什么要设置StackPanel的DataContext,虽然你可以设置Window的DataContext并进一步使用它,但是如果你想再尝试这个

  

XAML

 <StackPanel x:Name="stackPanel" DataContext="{Binding Person}">
  

xaml.cs

    public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        Person = new Person { FirstName = "Matt", LastName = "Smith" };
    }
    Person person;
    public Person Person
    {
        get { return person; }
        set { person = value; OnPropertyChanged("Person"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
}

或者代替设置StackPanel的DataContext,使用Window的dataContext和绑定文本块文本,如Person.FirstName .....

<TextBox x:Name="textBox_FirstName" Width="200" Margin="0,100,0,0" Text="{Binding Path=Person.FirstName, UpdateSourceTrigger=PropertyChanged}"  />
    <TextBox x:Name="textBox_LastName" Width="200" Margin="0,10,0,0" Text="{Binding Path=Person.LastName, UpdateSourceTrigger=PropertyChanged}" />
    <TextBlock x:Name="textBlock_FullName"  Background="LightBlue" Width="200" Margin="0,10,0,0" Text="{Binding Path=Person.FullName, UpdateSourceTrigger=PropertyChanged}"  />

答案 2 :(得分:1)

要添加到Abbas的答案,当你有一个无参数构造函数时,你可能会发现在应用MVVM时更频繁地发生这种情况,你也可以设置控件的DataContext方式。

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

    <Window.DataContext>
        <local:HelloWorldDataContextModel />   
    </Window.DataContext>    

    <Grid>        
        <TextBox HorizontalAlignment="Left" Height="23" Margin="222,127,0,0" TextWrapping="Wrap" Text="{Binding HelloWorld}" VerticalAlignment="Top" Width="120"/>    
    </Grid>
</Window>

使用我的或Abbas的方法你会得到相同的结果;但是当构造函数需要参数时,这样做是不值得的。