我目前正在开发Windows通用应用程序。我对XAML一般都很陌生,但对它有一些经验。
我遇到的问题是围绕UserControl绑定。我环顾四周,找不到具体问题的答案。
我有一个链接到ViewModel的XAML页面,这一切都正常。然后在那个页面上,我使用的是UserControl,它基本上只是一个包含一些内容的标题的面板。在该面板的内容中,我有另一个UserControl,它基本上只包含一个Label和TextBox。
当我将ViewModel中的内容绑定到ContentPanel UserControl时,一切正常,它会拾取我的ViewModel上下文并正确绑定。
但是,当我尝试绑定到包含ContentPanel的LabelledTextbox UserControl时,绑定失败,因为它只是在ContentPanel上查找ViewModel上的属性。
请参阅下面的代码
Page.xaml
<!--Page.xaml-->
<cc:ContentPanel PanelHeading="LEFT FOOT: Measurements" PanelHeadingBackground="{StaticResource OPCare.PanelHeader}">
<StackPanel>
<cc:LabelledTextbox LabelText="Malleoli Width" Text="test" />
<cc:LabelledTextbox LabelText="Met Head Width" />
</StackPanel>
</cc:ContentPanel>
ContentPanel.xaml
<!--ContentPanel UserControl-->
<UserControl
x:Class="OrthoticTabletApp.Controls.ContentPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:OrthoticTabletApp.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
x:Name="Parent">
<Grid DataContext="{Binding ElementName=Parent}">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Padding="10" Grid.Column="0" Grid.Row="0" Height="50" Background="{Binding Path=PanelHeadingBackground}">
<TextBlock Height="30" LineHeight="30" Text="{Binding Path=PanelHeading}" />
</Grid>
<Grid Padding="10" Grid.Column="0" Grid.Row="1" Background="White">
<ContentPresenter Content="{Binding Path=PanelBody}" />
</Grid>
</Grid>
</UserControl>
ContentPanel.xaml.cs
[ContentProperty(Name = "PanelBody")]
public sealed partial class ContentPanel : UserControl
{
public static readonly DependencyProperty PanelHeadingProperty = DependencyProperty.Register("PanelHeading", typeof(string), typeof(ContentPanel), new PropertyMetadata(""));
public string PanelHeading
{
get
{
return (string)GetValue(PanelHeadingProperty);
}
set
{
SetValue(PanelHeadingProperty, value);
}
}
public static readonly DependencyProperty PanelBodyProperty = DependencyProperty.Register("PanelBody", typeof(object), typeof(ContentPanel), new PropertyMetadata(null));
public object PanelBody
{
get
{
return (object)GetValue(PanelBodyProperty);
}
set
{
SetValue(PanelBodyProperty, value);
}
}
public Brush PanelHeadingBackground
{
get { return (Brush)GetValue(PanelHeadingBackgroundProperty); }
set { SetValue(PanelHeadingBackgroundProperty, value); }
}
public static readonly DependencyProperty PanelHeadingBackgroundProperty =
DependencyProperty.Register("PanelHeadingBackground", typeof(Brush), typeof(ContentPanel), new PropertyMetadata(null));
public ContentPanel()
{
this.InitializeComponent();
}
}
LabelledTextbox.xaml
<UserControl
x:Class="OrthoticTabletApp.Controls.LabelledTextbox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:OrthoticTabletApp.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="50"
d:DesignWidth="400"
x:Name="Parent">
<Grid DataContext="{Binding ElementName=Parent}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Padding="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="15" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Path=LabelText}" />
</Grid>
<Grid Grid.Column="1" Padding="10">
<TextBox Text="{Binding Path=Text}" />
</Grid>
</Grid>
</UserControl>
LabelledTextbox.xaml.cs
public sealed partial class LabelledTextbox : UserControl
{
public string LabelText
{
get { return (string)GetValue(LabelTextProperty); }
set { SetValue(LabelTextProperty, value); }
}
// Using a DependencyProperty as the backing store for LabelText. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LabelTextProperty =
DependencyProperty.Register("LabelText", typeof(string), typeof(LabelledTextbox), new PropertyMetadata(null));
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
// Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(LabelledTextbox), new PropertyMetadata(null));
public LabelledTextbox()
{
this.InitializeComponent();
}
}
答案 0 :(得分:0)
但是,当我尝试绑定到ContentPanel包含的LabelledTextbox UserControl时,绑定失败,因为它只是在ContentPanel上查找ViewModel上的属性。
如果我正确理解您已完成的操作,则ContentPanel
的某些属性会绑定到页面视图模型中的数据模型,并且LabelledTextbox
的属性会受到约束到其他viewmodel中的数据模型?
如果有,您可以为DataContext
中的LabelledTextbox
指定StackPanel
的{{1}},例如:{/ p>
ContentPanel
在您网页的视图模型中,您可以为<cc:ContentPanel PanelHeading="{x:Bind Heading}" PanelHeadingBackground="Azure">
<StackPanel>
<StackPanel.DataContext>
<local:LabelledTextboxViewModel x:Name="VM" />
</StackPanel.DataContext>
<cc:LabelledTextbox LabelText="{x:Bind VM.Lable1}" Text="test" />
<cc:LabelledTextbox LabelText="{x:Bind VM.Lable2}" />
</StackPanel>
</local:ContentPanel>
创建数据模型并初始化数据,例如:
ContentPanel
在LabelledTextboxViewModel中,您可以编写如下代码:
public BlankPage3ViewModel()
{
Heading = "LEFT FOOT: Measurements";
}
public string Heading { get; set; }
通常当我们按照MVVM模式开发项目时,数据模型不应该包含在viewmodel中,我这里只是为了清晰易行的交付,关键点是您可以为同一页面中的不同控件指定不同的public class LabelledTextboxViewModel
{
public LabelledTextboxViewModel()
{
Lable1 = "Malleoli Width";
Lable2 = "Met Head Width";
}
public string Lable1 { get; set; }
public string Lable2 { get; set; }
}
。