我对嵌套datacontext user-controls有一个问题。问题是ViewModel中的模型绑定在第一个user-control的DependencyProperty上。在第一个user-control中是第二个user-control。第二个user-control也有一个DependencyProperty。第一个user-control绑定在第二个user-control的那个DependencyProperty上。
主视图:
<UserControl x:Class="XXX.XXX.Hmi.Views.L1SetupViewerView"
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:prism="http://prismlibrary.com/"
xmlns:uc="clr-namespace:XXX.XXX.Hmi.UserControls"
d:DesignHeight="450"
d:DesignWidth="800"
prism:ViewModelLocator.AutoWireViewModel="True"
Background="{DynamicResource BaseBrush}"
Foreground="{DynamicResource TextBrush}"
mc:Ignorable="d">
.
.
.
<GroupBox Grid.Row="1" Header="Entry Section">
<uc:L1SetupViewerEntrySectionView Margin="8" Setup="{Binding L1Setup}" />
</GroupBox>
.
.
.
</UserControl>MainViewModel:
public class L1SetupViewerViewModel : ViewModelBase
{
private L1Setup _l1Setup;
private Pdi _pdi;
public L1SetupViewerViewModel()
{
Title = LanguageProvider.Instance.GetValue("L1SetupViewer_Window_Title");
LanguageProvider.Instance.UiCultureChanged += Instance_UiCultureChanged;
}
#region Properties
public L1Setup L1Setup
{
get { return _l1Setup; }
set { SetProperty(ref _l1Setup, value); }
}
public Pdi Pdi
{
get { return _pdi; }
set { SetProperty(ref _pdi, value); }
}
#endregion
#region Navigation
public override void OnNavigatedTo(NavigationContext navigationContext)
{
if (navigationContext.Parameters.ContainsKey("L1Setup"))
{
L1Setup = navigationContext.Parameters.GetValue<L1Setup>("L1Setup");
}
if (navigationContext.Parameters.ContainsKey("Pdi"))
{
Pdi = navigationContext.Parameters.GetValue<Pdi>("Pdi");
}
}
#endregion
private void Instance_UiCultureChanged(object sender, EventArgs e)
{
Title = LanguageProvider.Instance.GetValue("L1SetupViewer_Window_Title");
}
}First UserControl:
<UserControl x:Class="XXX.XXX.Hmi.UserControls.L1SetupViewerEntrySectionView"
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:uc="clr-namespace:XXX.XXX.Hmi.UserControls"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" SharedSizeGroup="c" />
<ColumnDefinition Width="*" SharedSizeGroup="c" />
<ColumnDefinition Width="*" SharedSizeGroup="c" />
<ColumnDefinition Width="*" SharedSizeGroup="c" />
<ColumnDefinition Width="*" SharedSizeGroup="c" />
<ColumnDefinition Width="*" SharedSizeGroup="c" />
<ColumnDefinition Width="*" SharedSizeGroup="c" />
</Grid.ColumnDefinitions>
<uc:L1SetupViewerCellControl Title="Over Speed"
Grid.Row="0"
Grid.Column="0"
Margin="0,0,5,0"
Value="{Binding Setup.EnOveSpd}" />
.
.
.
</Grid>
</UserControl>First UserControl CodeBehind:
public partial class L1SetupViewerEntrySectionView : UserControl
{
public L1Setup Setup
{
get { return (L1Setup)GetValue(SetupProperty); }
set { SetValue(SetupProperty, value); }
}
public static readonly DependencyProperty SetupProperty =
DependencyProperty.Register("Setup", typeof(L1Setup), typeof(L1SetupViewerEntrySectionView), new PropertyMetadata(null));
public L1SetupViewerEntrySectionView()
{
InitializeComponent();
this.DataContext = this;
}
}第二UserControl:
<UserControl x:Class="XXX.XXX.Hmi.UserControls.L1SetupViewerCellControl"
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="450"
d:DesignWidth="800"
mc:Ignorable="d">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Margin="0,0,3,0"
Text="{Binding Title}" />
<TextBox Grid.Column="1" Text="{Binding Value}" />
</Grid>
</UserControl>Second UserControl CodeBehind:
public partial class L1SetupViewerCellControl : UserControl
{
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(L1SetupViewerCellControl), new PropertyMetadata(string.Empty));
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(string), typeof(L1SetupViewerCellControl), new PropertyMetadata(string.Empty));
public L1SetupViewerCellControl()
{
InitializeComponent();
this.DataContext = this;
}
}如果运行应用程序,则会得到以下绑定错误:
System.Windows.Data Error: 40 : BindingExpression path error: 'L1Setup' property not found on 'object' ''L1SetupViewerCellControl' (Name='')'. BindingExpression:Path=L1Setup.EnPor1OutDia; DataItem='L1SetupViewerCellControl' (Name=''); target element is 'L1SetupViewerCellControl' (Name=''); target property is 'Value' (type 'String')我在stackOverflow上尝试了几个答案,没有什么对我有用,我也不明白有什么不对。
发布于 2019-09-17 14:04:55
在this.DataContext = this上设置L1SetupViewerEntrySectionView会破坏来自L1SetupViewerView的数据上下文的继承,这就是为什么绑定到L1Setup失败的原因。
与其在代码背后显式设置DataContext,不如在UserControl中设置根元素的DataContext,如下所示:
<Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}>在每个绑定上...or源:
<uc:L1SetupViewerCellControl ...
Value="{Binding Setup.EnOveSpd, RelativeSource={RelativeSource AncestorType=UserControl}}" />同样的情况也适用于L1SetupViewerCellControl,即从构造函数中删除this.DataContext = this并使用RelativeSource绑定到Value属性。
<TextBox Grid.Column="1" Text="{Binding Value, RelativeSource={RelativeSource AncestorType=UserControl}}" />https://stackoverflow.com/questions/57975922
复制相似问题