WPF binding a nested textbox's text is not working
I have a XAML code as follows:
<UserControl x:Class="LabsterApp.TestExplorer.TestExplorer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:TestExplorer="clr-namespace:LabsterApp.TestExplorer" MinHeight="300">
<Grid>
<StackPanel MinWidth="120">
<TreeView/>
<Grid Name="TestInfo">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox Text="Name:" Grid.Row="0" Grid.Column="0"/开发者_C百科>
<TextBox Text="{Binding ElementName=CurrentTestInfo, Path=TestName}" Grid.Row="0" Grid.Column="1"/>
</Grid>
</StackPanel>
</Grid>
</UserControl>
I set the whole control's data context to be its viewmodel (in the code behind):
public TestExplorer()
{
viewModel = new TreeExplorerViewModel();
DataContext = viewModel;
InitializeComponent();
}
The viewmodel has a CurrentTestInfo
object which has a TestName
property (all public). At some point, I update the CurrentTestInfo
(creating a new object each time) but the text in the textbox is not updated. I've tried using:
<TextBox Text="{Binding Path=CurrentTestInfo.TestName}" Grid.Row="0" Grid.Column="1"/>
instead and also tried a nested binding (textbox\text\binding tags).
The relevant viewmodel part:public void TreeNodeSelected(object selectedNode)
{
var node = (FolderTreeNode)selectedNode;
if (!node.IsFolder)
{
HandleTest(node);
return;
}
HandleFolderNode(node);
}
This is a test node so we go to HandleTest
:
// puts null/"" in all the fields:
CurrentTestInfo.Clear();
// locate the node in the currentData table
DataRow currentRow = null;
foreach (DataRow dataRow in currentData.Rows)
{
if (dataRow["TestID"].ToString().Equals(string.Empty)) continue;
if (node.TestId == Guid.Parse(dataRow["TestID"].ToString()))
{
currentRow = dataRow;
break;
}
}
CurrentTestInfo.TestName = currentRow["TestName"].ToString();
CurrentTestInfo.Owner = currentRow["TestOwner"].ToString();
CurrentTestInfo.LastUpdated = DateTime.Parse(currentRow["TestDate"].ToString());
TestInfo class:
public class TestInfo : INotifyPropertyChanged
{
private string testName;
public string TestName
{
get { return testName; }
set
{
testName = value;
OnPropertyChanged(new PropertyChangedEventArgs("TestName"));
}
}
private DateTime? lastUpdated;
public DateTime? LastUpdated
{
get { return lastUpdated; }
set
{
lastUpdated = value;
OnPropertyChanged(new PropertyChangedEventArgs("LastUpdated"));
}
}
private string owner;
public string Owner
{
get { return owner; }
set
{
owner = value;
OnPropertyChanged(new PropertyChangedEventArgs("Owner"));
}
}
public void Clear()
{
TestName = string.Empty;
Owner = string.Empty;
LastUpdated = null;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
}
What am I doing wrong?
Thanks.
In your binding, 'ElementName' is used when you want to bind to a XAML element's property. For example, if you were binding to another TextBox's Text property.
Change you binding back to:
Text="{Binding Path=CurrentTestInfo.TestName}"
Also, verify your ViewModel implements INotifyPropertyChanged. Your ViewModel needs to be raising the PropertyChanged event so that UI controls know to refresh themselves.
Does your view model and TestInfo
type implement INotifyPropertyChanged? Are you invoking the PropertyChanged
event when the CurrentTestInfo
and TestName
properties are set?
精彩评论