[英]How to Bind a DataContext to ViewModel inside window's DataContext?
我目前的視圖如下所示:
<Window>
<DockPanel>
<Menu>
...
</Menu>
<StackPanel>
<Grid>
...
</Grid>
<Separator>
<Grid>
<Frame Source="ADifferentView.xaml" DataContext="{Binding ADifferentViewModel}">
<Frame...>
<Frame...>
</Grid>
</StackPanel>
</DockPanel>
</Window>
ViewModel 聲明為:
public ResultsViewModel ADifferentViewModel{ get; set; }
並在構造函數中初始化。
ADifferentViewModel 是 Window 的 ViewModel 中的一個變量(已正確鏈接並正常工作)。 但是,框架與該變量的綁定似乎沒有鏈接。
我的直覺表明這是由於需要獲取 Window 的上下文。 我試過了:
DataContext="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=ADifferentViewModel}"
DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}, Path=ADifferentViewModel}"
然而,這些都不起作用。 我還嘗試將 Window 更改為 DockPanel、StackPanel 和 Grid,但均無濟於事。
任何建議將不勝感激,希望這足夠清楚。 請詢問您是否需要任何詳細信息
由於某種原因,似乎Frame
的 DataContext 沒有落入其內容中。但是,您可以從Frame
的LoadCompleted
事件中受益,像這樣手動分配DataContext
:
.xaml
<Frame
x:Name="MyFrame"
LoadCompleted="MyFrame_OnLoadCompleted"
Source="ADifferentView.xaml" DataContext="{Binding ADifferentViewModel}"/>
.xaml.cs
private void MyFrame_OnLoadCompleted(object sender, NavigationEventArgs e)
{
if (MyFrame.Content is FrameworkElement content)
content.DataContext = MyFrame.DataContext;
}
您的解釋和演示代碼不足以回答您的問題。 我將向您展示一些綁定示例。
我希望這足以讓您了解問題的原因。
例一。
設置 DataContext 並使用 TextBox 檢查其值。
using System.Windows;
namespace Core2022.SO.HarryAdams
{
public partial class DataContextBindingWindow : Window
{
private readonly MainViewModel viewModel;
public DataContextBindingWindow()
{
InitializeComponent();
viewModel = new MainViewModel();
viewModel.ADifferentViewModel = new ResultsViewModel();
viewModel.ADifferentViewModel.Number = 12345678;
DataContext = viewModel;
}
}
public class ResultsViewModel
{
public int Number { get; set; }
}
public class MainViewModel
{
public ResultsViewModel? ADifferentViewModel { get; set; }
}
}
<Window x:Class="Core2022.SO.HarryAdams.DataContextBindingWindow"
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:Core2022.SO.HarryAdams"
mc:Ignorable="d"
Title="DataContextBindingWindow" Height="450" Width="800">
<StackPanel>
<Frame x:Name="frame" Height="100" DataContext="{Binding ADifferentViewModel}"/>
<TextBlock Text="{Binding DataContext.Number, ElementName=frame}"/>
</StackPanel>
</Window>
在此示例中,您可以看到 DataContext 正確綁定並顯示正確的值。
第二個例子。
由於 DataContext 綁定工作正常,我假設您的意思是 DataContext 不是 Frame,而是 Page «ADifferentView»。
<Page x:Class="Core2022.SO.HarryAdams.ADifferentView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Core2022.SO.HarryAdams"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="ADifferentView">
<Grid Background="LightSkyBlue">
<TextBlock Text="{Binding Number}"/>
</Grid>
</Page>
<Frame x:Name="frame" Height="100" DataContext="{Binding ADifferentViewModel}"
Source="/SO/HarryAdams/ADifferentView.xaml"/>
在此示例中,頁面文本框收到一個錨定錯誤。 原因是 Page 用於表示 Frame.Content 屬性。 由於此屬性中未設置任何內容,因此頁面數據上下文沒有綁定 object。
同時,即使將 FindAncestor 類型顯式綁定到 Frame 或 Window 也不能解決問題:
<Page x:Class="Core2022.SO.HarryAdams.ADifferentView"
DataContext="{Binding DataContext,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Frame}}}"
第三個例子。
在導航事件中將 Page DataContext 綁定到 object。
<StackPanel>
<Frame x:Name="frame" Height="100" DataContext="{Binding ADifferentViewModel}"
Source="/SO/HarryAdams/ADifferentView.xaml"
Navigated="OnNavigated"/>
<TextBlock Text="{Binding DataContext.Number, ElementName=frame}"/>
</StackPanel>
<x:Code>
<![CDATA[
private void OnNavigated(object sender, NavigationEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
FrameworkElement child = (FrameworkElement)e.Content;
child.SetBinding(DataContextProperty, new Binding("DataContext") { Source = element});
}
]]>
</x:Code>
</Window>
第四個例子。
此示例對於 WPF 頁面更為典型。
他們要么創建自己的 DataContext,要么從 App 獲取。
<Application.Resources>
<harryadams:MainViewModel x:Key="mainVM">
<harryadams:MainViewModel.ADifferentViewModel>
<harryadams:ResultsViewModel Number="1234567"/>
</harryadams:MainViewModel.ADifferentViewModel>
</harryadams:MainViewModel>
</Application.Resources>
<Page x:Class="Core2022.SO.HarryAdams.ADifferentView"
DataContext="{Binding ADifferentViewModel, Source={StaticResource mainVM}}"
第五例。
這個例子是比較典型的 WPF+MVVM 頁面。 在這種情況下,錨點 object 在 Frame Content 中傳遞,頁面類型在 DataTemplate 中指定:
<StackPanel>
<Frame x:Name="frame" Height="100" Content="{Binding ADifferentViewModel}">
<Frame.ContentTemplate>
<DataTemplate>
<local:ADifferentView/>
</DataTemplate>
</Frame.ContentTemplate>
</Frame>
<TextBlock Text="{Binding Content.Number, ElementName=frame}"/>
</StackPanel>
</Window>
您還可以使用默認數據模板:
<Window.Resources>
<DataTemplate DataType="{x:Type local:ResultsViewModel}">
<local:ADifferentView/>
</DataTemplate>
</Window.Resources>
<StackPanel>
<Frame x:Name="frame" Height="100" Content="{Binding ADifferentViewModel}"/>
<TextBlock Text="{Binding Content.Number, ElementName=frame}"/>
</StackPanel>
</Window>
第六個例子。
Frame+Page 經常用在錯誤的地方。
在絕大多數情況下,應改用 UserControl。 在這種情況下,對於大多數元素,所有綁定和傳遞 DataContext 開始以典型方式工作。
<UserControl x:Class="Core2022.SO.HarryAdams.ADifferentView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Core2022.SO.HarryAdams"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="LightSkyBlue">
<TextBlock Text="{Binding Number}"/>
</Grid>
</UserControl>
<Window x:Class="Core2022.SO.HarryAdams.DataContextBindingWindow"
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:Core2022.SO.HarryAdams"
mc:Ignorable="d"
Title="DataContextBindingWindow" Height="450" Width="800">
<StackPanel>
<local:ADifferentView x:Name="frame" Height="100" DataContext="{Binding ADifferentViewModel}"/>
<TextBlock Text="{Binding DataContext.Number, ElementName=frame}"/>
</StackPanel>
</Window>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.