Wpf + Caliburn Micro:将文本框绑定到自定义对象
Wpf + Caliburn Micro: Binding Textbox to a custom object
我使用 Wpf 4.5 和 Caliburn Micro 2.0.2。
我想将文本框绑定到 属性 视图模型。 属性(称为 ResultData)是来自 class TextXmlData 的对象。 class 是从 xsd 自动生成的 class。我用微软Xsd.exe来制作。
这是视图模型
public class ShellViewModel : PropertyChangedBase, IHaveDisplayName
{
public string DisplayName { get; set; }
private TestXmlData _resultData;
public TestXmlData ResultData
{
get { return _resultData; }
set
{
_resultData = value;
NotifyOfPropertyChange(() => _resultData);
}
}
public ShellViewModel()
{
DisplayName = "Shell Window";
}
public void CreateObject()
{
String xmlData = "<TestXmlData><Id>88</Id><Name>What a name</Name></TestXmlData>";
if (ResultData == null) { ResultData = new TestXmlData(); }
XmlSerializer oXmlSerializer = new XmlSerializer(ResultData.GetType());
ResultData = (TestXmlData)oXmlSerializer.Deserialize(new StringReader(xmlData));
// at this point the debugger shows that the ResultData is correctly filled,
// the Name is definitely not empty
}
}
这就是风景
<UserControl x:Class="CMWpfXmlSerializer2Ways.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
<Grid Width="300" Height="300">
<StackPanel Width="200"
Height="100"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Button x:Name="CreateObject"
Width="190"
Content="Create Object from XML" />
<TextBox Width="190"
DataContext="{Binding ResultData}"
Text="{Binding Name}" />
</StackPanel>
</Grid>
</UserControl>
并且文本框始终显示为空!
我也尝试过使用 Text="{Binding ResultData.Name}",但 TextBox 仍然显示为空。
任何人都可以帮助并告诉我上面的代码有什么问题吗?
请随时修改代码。
提前致谢。
ResultData 是 ViewModel 的 属性。因此,您需要在更高级别将 ViewModel 设置为 DataContext,然后您可以使用它 属性 作为较低级别的绑定源。
为了 运行 您的示例,我做了一些更改 运行 如下所示:
<TextBox x:Name="tbName" DataContext="{Binding ResultData}" Text="{Binding Name}" />
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ShellViewModel vm = new ShellViewModel();
vm.CreateObject();
this.DataContext = vm;
}
...
///
public class ShellViewModel : INotifyPropertyChanged
{
public string DisplayName { get; set; }
private TestXmlData _resultData;
public TestXmlData ResultData
{
get { return _resultData; }
set
{
_resultData = value;
OnPropertyChanged("ResultData");
}
}
public void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
public ShellViewModel()
{
DisplayName = "Shell Window";
}
public void CreateObject()
{
String xmlData = "<TestXmlData><Id>88</Id><Name>What a name</Name></TestXmlData>";
if (ResultData == null) { ResultData = new TestXmlData(); }
XmlSerializer oXmlSerializer = new XmlSerializer(ResultData.GetType());
ResultData = (TestXmlData)oXmlSerializer.Deserialize(new StringReader(xmlData));
// at this point the debugger shows that the ResultData is correctly filled,
// the Name is definitely not empty
}
public event PropertyChangedEventHandler PropertyChanged;
}
您是否启用了 Caliburn.MIcro 调试?这将从您的 BootStrapper 完成。这将告诉我们您的视图和视图模型是否正确绑定。
通常放在bootstrapper的CTOR中
LogManager.GetLog = 类型 => new DebugLog(类型);
由于您在 shellview 中使用了 UserControl,因此我希望看到您的 BootStrapper。
我怀疑有些地方不正确或命名空间设置不正确,这会导致绑定错误。
在我反复阅读大家的意见、提示、建议和我的代码后,偶然发现了问题的原因。这是我自己的错误(是的,我的愚蠢错误)
我在 NotifyOfPropertyChange 上使用了 支持字段 _resultData 而不是 属性 名称结果数据! (请在视图模型中查看 属性 ResultData 的 setter)
非常感谢大家!
我使用 Wpf 4.5 和 Caliburn Micro 2.0.2。
我想将文本框绑定到 属性 视图模型。 属性(称为 ResultData)是来自 class TextXmlData 的对象。 class 是从 xsd 自动生成的 class。我用微软Xsd.exe来制作。
这是视图模型
public class ShellViewModel : PropertyChangedBase, IHaveDisplayName
{
public string DisplayName { get; set; }
private TestXmlData _resultData;
public TestXmlData ResultData
{
get { return _resultData; }
set
{
_resultData = value;
NotifyOfPropertyChange(() => _resultData);
}
}
public ShellViewModel()
{
DisplayName = "Shell Window";
}
public void CreateObject()
{
String xmlData = "<TestXmlData><Id>88</Id><Name>What a name</Name></TestXmlData>";
if (ResultData == null) { ResultData = new TestXmlData(); }
XmlSerializer oXmlSerializer = new XmlSerializer(ResultData.GetType());
ResultData = (TestXmlData)oXmlSerializer.Deserialize(new StringReader(xmlData));
// at this point the debugger shows that the ResultData is correctly filled,
// the Name is definitely not empty
}
}
这就是风景
<UserControl x:Class="CMWpfXmlSerializer2Ways.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
<Grid Width="300" Height="300">
<StackPanel Width="200"
Height="100"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Button x:Name="CreateObject"
Width="190"
Content="Create Object from XML" />
<TextBox Width="190"
DataContext="{Binding ResultData}"
Text="{Binding Name}" />
</StackPanel>
</Grid>
</UserControl>
并且文本框始终显示为空!
我也尝试过使用 Text="{Binding ResultData.Name}",但 TextBox 仍然显示为空。
任何人都可以帮助并告诉我上面的代码有什么问题吗? 请随时修改代码。 提前致谢。
ResultData 是 ViewModel 的 属性。因此,您需要在更高级别将 ViewModel 设置为 DataContext,然后您可以使用它 属性 作为较低级别的绑定源。
为了 运行 您的示例,我做了一些更改 运行 如下所示:
<TextBox x:Name="tbName" DataContext="{Binding ResultData}" Text="{Binding Name}" />
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ShellViewModel vm = new ShellViewModel();
vm.CreateObject();
this.DataContext = vm;
}
...
///
public class ShellViewModel : INotifyPropertyChanged
{
public string DisplayName { get; set; }
private TestXmlData _resultData;
public TestXmlData ResultData
{
get { return _resultData; }
set
{
_resultData = value;
OnPropertyChanged("ResultData");
}
}
public void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
public ShellViewModel()
{
DisplayName = "Shell Window";
}
public void CreateObject()
{
String xmlData = "<TestXmlData><Id>88</Id><Name>What a name</Name></TestXmlData>";
if (ResultData == null) { ResultData = new TestXmlData(); }
XmlSerializer oXmlSerializer = new XmlSerializer(ResultData.GetType());
ResultData = (TestXmlData)oXmlSerializer.Deserialize(new StringReader(xmlData));
// at this point the debugger shows that the ResultData is correctly filled,
// the Name is definitely not empty
}
public event PropertyChangedEventHandler PropertyChanged;
}
您是否启用了 Caliburn.MIcro 调试?这将从您的 BootStrapper 完成。这将告诉我们您的视图和视图模型是否正确绑定。
通常放在bootstrapper的CTOR中 LogManager.GetLog = 类型 => new DebugLog(类型);
由于您在 shellview 中使用了 UserControl,因此我希望看到您的 BootStrapper。
我怀疑有些地方不正确或命名空间设置不正确,这会导致绑定错误。
在我反复阅读大家的意见、提示、建议和我的代码后,偶然发现了问题的原因。这是我自己的错误(是的,我的愚蠢错误)
我在 NotifyOfPropertyChange 上使用了 支持字段 _resultData 而不是 属性 名称结果数据! (请在视图模型中查看 属性 ResultData 的 setter)
非常感谢大家!