繁体   English   中英

wpf mvvm嵌套用户控件datacontext

[英]wpf mvvm nested user controls datacontext

我对嵌套user-controlsdatacontext有问题。 问题在于ViewModel中的模型绑定到第一个user-controlDependencyProperty上。 在第一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");
    }
}

第一个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>

第一个UserControl代码背后:

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>

第二个UserControl代码背后:

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上尝试了几个答案,但对我没有任何帮助,我也没弄错。

设置this.DataContext = thisL1SetupViewerEntrySectionView打破从数据上下文的继承L1SetupViewerView ,这就是为什么在结合L1Setup失败。

而不是在后面的代码中显式设置DataContext ,您应该像这样在UserControl设置根元素的DataContext

<Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}>

...或每个绑定的来源:

<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}}" />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM