WPF 数据绑定到第二个视图
Posted
技术标签:
【中文标题】WPF 数据绑定到第二个视图【英文标题】:WPF Databinding to second view 【发布时间】:2022-01-01 00:27:26 【问题描述】:我在这个问题上花了一天多一点的时间,我绝对是无能的。 如果我单击按钮以显示它打开的第二个视图,但没有内容。 我什至得到了视图模型中的断点。 为此,我将所有内容简化为一个简单的文本框和文本块,它们关闭显示相同的数据,但它们没有。即使在输入框后,它们也不会显示任何内容,该块不会更新。 但是我尝试过的数据绑定不起作用。有人有想法吗?
提前致谢
我的第二个视图
<Window x:Class="AoE4_BO_Overlay.Views.EditorView"
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"
xmlns:local="clr-namespace:AoE4_BO_Overlay.Views" xmlns:viewmodels="clr-namespace:AoE4_BO_Overlay.ViewModels" d:DataContext="d:DesignInstance Type=viewmodels:EditorViewModel"
mc:Ignorable="d"
Title="EditorView" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="20" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<TextBlock Text="Binding Path=FirstName" Grid.Column="0" Grid.Row="2"/>
<TextBox Text="Binding Path=FirstName , Mode=OneWay" Grid.Column="0" Grid.Row="1"/>
</Grid>
我的视图模型
internal class EditorViewModel : Conductor<object>
private string _firstName = "Tom";
public EditorViewModel()
public string FirstName
get
return _firstName;
set
_firstName = value;
NotifyOfPropertyChange(() => FirstName);
我怎么称呼他们两个
public void CreateBO_Click(object sender, RoutedEventArgs e)
EditorView createBO = new EditorView();
ActivateItemAsync(new EditorViewModel());
createBO.Show();
添加信息
public partial class EditorView : Window
public EditorView()
DataContext = new EditorViewModel();
InitializeComponent();
【问题讨论】:
【参考方案1】:您有两个不同的问题:
1.输入文本框不会更改绑定属性:
这是预期的,因为您明确使用 OneWay 绑定。 OneWay 绑定意味着属性更新用户界面,而不是相反。 所以更改 FirstName 应该会更新 TextBox,但更改 TextBox 不会更新 FirstName。
有趣的是,如果您只是省略 Mode = OneWay
部分,它应该可以工作 - 因为 TextBoxes 应该默认使用 TwoWay 绑定。我建议您将 TextBox 绑定明确定义为 Mode = TwoWay
2。您的视图使用空的 TextBlock / TextBox 进行初始化
这个更难确定,因为您没有向我们展示您设置 DataContext 的位置。当我在InitializeComponent()
之后而不是之前设置 DataContext 时,这通常会发生在我身上。您可以在绑定初始化之前设置 DataContext(作为 InizializeComponent() 的一部分),或者您必须在属性上引发 NotifyPropertyChanged 以在之后更新 UI。
如果这不是原因,您可能希望在输出控制台中启用 WPF 绑定错误 - 这通常可以让您很好地了解绑定失败的位置。 Visual Studio 有一个选项。它应该位于此处:
工具 -> 选项 -> 调试 -> 输出窗口 -> WPF 跟踪设置 -> 数据绑定 -> 全部
【讨论】:
首先,非常感谢您的回答。 非常感谢!我需要搜索一下,但我找到了。 “DataContext = 新的 EditorViewModel();”是我错过的那条线。 这听起来不对。您确定 EditorViewModel 的新实例是您想要的吗?通常的做法是在InitializeComponent();
之前使用DataContext = this;
确定吗?不。我读了一点并尝试了有效的方法。我的解决方案产生了预期的结果。如果我用this
替换new EditorViewModel()
,它就不再起作用了。我不知道它是否无能为力,但我在项目中使用了 Caliburn.Micro。只是为了获得更多信息,我将相关课程添加到帖子中。【参考方案2】:
我相信您在这里尝试的是在第一个视图中显示您的第二个视图 (EditorView
)(而不是作为弹出窗口 - 如果您打算将其作为弹出窗口,请使用 WindowManager
而不是 @ 987654324@).
要实现这一点,您需要更改的一件事是确保您的第二个 View 是 UserControl 而不是 Window。
// EditorView.xaml.cs
public partial class EditorView : UserControl
// EditView.xaml
<UserControl x:Class="AoE4_BO_Overlay.Views.EditorView"
此外,由于您使用的是ActivateItemAsync
,因此您需要确保您的 FirstView 包含名称为“ActiveItem”的 ContendControl。
// FirstView.xaml
<ContentControl x:Name="ActiveItem"/>
对ActivateItemAsync
的调用将使用此控件加载您的第二个ViewModel (EditorViewModel
) 的视图。有了这个,您现在可以使用ActivateItemAsync
方法来加载视图。
public async Task CreateBO_Click(object sender, RoutedEventArgs e)
await ActivateItemAsync(new EditorViewModel());
请注意,ActivateItemAsync
方法支持异步调用,最好异步调用该方法。
需要注意的另一点是,如果您使用的是 Caliburn Micro,并且 View/ViewModel 存储在推荐的文件夹/命名空间结构中,则不需要显式指定 DataContext,如 OP 中所示。 Caliburn Micro 使用命名约定来关联适当的视图-视图模型对。更多相关信息可以在official documentation
中找到【讨论】:
以上是关于WPF 数据绑定到第二个视图的主要内容,如果未能解决你的问题,请参考以下文章
从数组中删除 - 致命错误:索引超出范围 - SwiftUI 绑定
windows phoneCollectionViewSource的妙用