在 WPF 中将元素绑定到 DataTemplate Window
Binding elements into a DataTemplate in WPF Window
根据 CantidadLlantas 属性,我的 window 中有五个 DataTemplate 定义,我选择其中一个来显示它。到这里为止一切正常。
但是,在每个 DataTemplate 中都有一些带有文本 属性 绑定到我的 ViewModel 中的一个 属性 的文本框,如果我在 TextBoxes 中显示这些相同的属性DataTemplates 显示的值正常,就像绑定没有绑定到 DataTemplates 一样...为什么?
下一个模板比较简单:
<Window.Resources>
<DataTemplate x:Name="Llantas2Template" x:Key="Llantas2Template" DataType="ContentControl">
<Grid Name="grdLlantas">
<Border Name="borLlantas" BorderBrush="Black" BorderThickness="1" Margin="0,0,0,0" Background="DarkSeaGreen" />
<Rectangle Fill="Yellow" HorizontalAlignment="Left" Height="30" Stroke="Black" VerticalAlignment="Top" Width="5" Margin="0,16,0,0" />
<Rectangle Fill="Yellow" HorizontalAlignment="Left" Height="30" Stroke="Black" VerticalAlignment="Top" Width="5" Margin="0,130,0,0" />
<Rectangle HorizontalAlignment="Left" Height="175" Stroke="Black" StrokeThickness="3" VerticalAlignment="Top" Width="70" Margin="20,10,10,10" />
<Line X1="230" Y1="10" X2="230" Y2="150" Stroke="Black" StrokeThickness="3" />
<Ellipse Fill="Black" Height="25" Width="10" StrokeThickness="2" Stroke="Black" Margin="180,0,0,10"/>
<TextBox Name="txtLlanta2" Margin="200,10,20,20" ToolTipService.ToolTip="Llanta trasera derecha"
Width="60" Height="25" HorizontalAlignment="Left" VerticalAlignment="Top"
Text="{Binding Llanta2, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Name="txtLlanta1" Margin="200,150,20,10" ToolTipService.ToolTip="Llanta trasera izquierda"
Width="60" Height="25" HorizontalAlignment="Left" VerticalAlignment="Top"
Text="{Binding Llanta1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</DataTemplate>
然后在 window 中,我将 ContentControl 声明到 StackPanel 中,其可见性取决于我的 ViewModel 中的 属性,这工作正常:
<StackPanel Name="stkLlantas" Grid.Row="2" Visibility="{Binding IsVisibilityTemplate}" >
<!--Aquí se pondrá el UserControl con el Template de Llantas que corresponde-->
<ContentControl Grid.Row="2" Name="LlantasContent"
VerticalAlignment="Stretch" HorizontalAlignment="Center"
Margin="0,10,0,10" />
</StackPanel>
模板选择在后面:
#region DefineTemplate
private void DefineTemplate()
{
switch (cantidadLlantas)
{
case 2:
LlantasContent.ContentTemplate = (DataTemplate)this.FindResource("Llantas2Template");
break;
case 4:
LlantasContent.ContentTemplate = (DataTemplate)this.FindResource("Llantas4Template");
break;
case 6:
LlantasContent.ContentTemplate = (DataTemplate)this.FindResource("Llantas6Template");
break;
case 8:
LlantasContent.ContentTemplate = (DataTemplate)this.FindResource("Llantas8Template");
break;
case 10:
LlantasContent.ContentTemplate = (DataTemplate)this.FindResource("Llantas10Template");
break;
default:
LlantasContent.ContentTemplate = null;
break;
}
}
#endregion
在后面,我为 window 定义了 DataContext:
UnidadLlantasVM viewModel;
int cantidadLlantas;
public wUnidadLlantas(string _IDUni, int _CantidadLlantas)
{
this.Loaded += (s, a) =>
{
cantidadLlantas = _CantidadLlantas;
viewModel = new UnidadLlantasVM();
viewModel.IDUni = _IDUni;
viewModel.CantidadLlantas = _CantidadLlantas;
this.DataContext = viewModel;
DefineTemplate();
};
InitializeComponent();
}
在xaml中:
<Window x:Class="MTTO.wUnidadLlantas"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
出于测试目的,我在 window 中添加了文本框,其属性应该显示在模板中,这里工作正常,附上图像:
在 window 中播种的所有数据都是我的 ViewModel 的属性并且工作正常,但在模板中没有,图片中的 TextBoxes 应该与红色指向的 TextBoxes 相同。发生什么事?我有一个相同的 Silverlight 项目,并且工作正常...
可能您需要将 DataContext 绑定到 ContentControl 的内容 属性(我觉得这有点像 WPF 中的设计缺陷,但没关系)。
<StackPanel Name="stkLlantas" Grid.Row="2" Visibility="{Binding IsVisibilityTemplate}" >
<!--Aquí se pondrá el UserControl con el Template de Llantas que corresponde-->
<ContentControl Grid.Row="2" Name="LlantasContent"
Content="{Binding}"
VerticalAlignment="Stretch" HorizontalAlignment="Center"
Margin="0,10,0,10" />
</StackPanel
顺便说一下,考虑使用 ContentTemplateSelector
作为您在 DefineTemplate
中所做的事情。这是模板选择的默认 API。
您可以将现有代码和逻辑从定义模板移动到 SelectTemplate
.
https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.contentcontrol.contenttemplateselector?view=windowsdesktop-6.0
https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.datatemplateselector.selecttemplate?view=windowsdesktop-6.0
根据 CantidadLlantas 属性,我的 window 中有五个 DataTemplate 定义,我选择其中一个来显示它。到这里为止一切正常。
但是,在每个 DataTemplate 中都有一些带有文本 属性 绑定到我的 ViewModel 中的一个 属性 的文本框,如果我在 TextBoxes 中显示这些相同的属性DataTemplates 显示的值正常,就像绑定没有绑定到 DataTemplates 一样...为什么?
下一个模板比较简单:
<Window.Resources>
<DataTemplate x:Name="Llantas2Template" x:Key="Llantas2Template" DataType="ContentControl">
<Grid Name="grdLlantas">
<Border Name="borLlantas" BorderBrush="Black" BorderThickness="1" Margin="0,0,0,0" Background="DarkSeaGreen" />
<Rectangle Fill="Yellow" HorizontalAlignment="Left" Height="30" Stroke="Black" VerticalAlignment="Top" Width="5" Margin="0,16,0,0" />
<Rectangle Fill="Yellow" HorizontalAlignment="Left" Height="30" Stroke="Black" VerticalAlignment="Top" Width="5" Margin="0,130,0,0" />
<Rectangle HorizontalAlignment="Left" Height="175" Stroke="Black" StrokeThickness="3" VerticalAlignment="Top" Width="70" Margin="20,10,10,10" />
<Line X1="230" Y1="10" X2="230" Y2="150" Stroke="Black" StrokeThickness="3" />
<Ellipse Fill="Black" Height="25" Width="10" StrokeThickness="2" Stroke="Black" Margin="180,0,0,10"/>
<TextBox Name="txtLlanta2" Margin="200,10,20,20" ToolTipService.ToolTip="Llanta trasera derecha"
Width="60" Height="25" HorizontalAlignment="Left" VerticalAlignment="Top"
Text="{Binding Llanta2, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Name="txtLlanta1" Margin="200,150,20,10" ToolTipService.ToolTip="Llanta trasera izquierda"
Width="60" Height="25" HorizontalAlignment="Left" VerticalAlignment="Top"
Text="{Binding Llanta1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</DataTemplate>
然后在 window 中,我将 ContentControl 声明到 StackPanel 中,其可见性取决于我的 ViewModel 中的 属性,这工作正常:
<StackPanel Name="stkLlantas" Grid.Row="2" Visibility="{Binding IsVisibilityTemplate}" >
<!--Aquí se pondrá el UserControl con el Template de Llantas que corresponde-->
<ContentControl Grid.Row="2" Name="LlantasContent"
VerticalAlignment="Stretch" HorizontalAlignment="Center"
Margin="0,10,0,10" />
</StackPanel>
模板选择在后面:
#region DefineTemplate
private void DefineTemplate()
{
switch (cantidadLlantas)
{
case 2:
LlantasContent.ContentTemplate = (DataTemplate)this.FindResource("Llantas2Template");
break;
case 4:
LlantasContent.ContentTemplate = (DataTemplate)this.FindResource("Llantas4Template");
break;
case 6:
LlantasContent.ContentTemplate = (DataTemplate)this.FindResource("Llantas6Template");
break;
case 8:
LlantasContent.ContentTemplate = (DataTemplate)this.FindResource("Llantas8Template");
break;
case 10:
LlantasContent.ContentTemplate = (DataTemplate)this.FindResource("Llantas10Template");
break;
default:
LlantasContent.ContentTemplate = null;
break;
}
}
#endregion
在后面,我为 window 定义了 DataContext:
UnidadLlantasVM viewModel;
int cantidadLlantas;
public wUnidadLlantas(string _IDUni, int _CantidadLlantas)
{
this.Loaded += (s, a) =>
{
cantidadLlantas = _CantidadLlantas;
viewModel = new UnidadLlantasVM();
viewModel.IDUni = _IDUni;
viewModel.CantidadLlantas = _CantidadLlantas;
this.DataContext = viewModel;
DefineTemplate();
};
InitializeComponent();
}
在xaml中:
<Window x:Class="MTTO.wUnidadLlantas"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
出于测试目的,我在 window 中添加了文本框,其属性应该显示在模板中,这里工作正常,附上图像:
在 window 中播种的所有数据都是我的 ViewModel 的属性并且工作正常,但在模板中没有,图片中的 TextBoxes 应该与红色指向的 TextBoxes 相同。发生什么事?我有一个相同的 Silverlight 项目,并且工作正常...
可能您需要将 DataContext 绑定到 ContentControl 的内容 属性(我觉得这有点像 WPF 中的设计缺陷,但没关系)。
<StackPanel Name="stkLlantas" Grid.Row="2" Visibility="{Binding IsVisibilityTemplate}" >
<!--Aquí se pondrá el UserControl con el Template de Llantas que corresponde-->
<ContentControl Grid.Row="2" Name="LlantasContent"
Content="{Binding}"
VerticalAlignment="Stretch" HorizontalAlignment="Center"
Margin="0,10,0,10" />
</StackPanel
顺便说一下,考虑使用 ContentTemplateSelector
作为您在 DefineTemplate
中所做的事情。这是模板选择的默认 API。
您可以将现有代码和逻辑从定义模板移动到 SelectTemplate
.
https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.contentcontrol.contenttemplateselector?view=windowsdesktop-6.0 https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.datatemplateselector.selecttemplate?view=windowsdesktop-6.0