C# 如何从子绑定使用父内容控件?
我目前有以下代码:C# 如何从子绑定使用父内容控件?,c#,wpf,data-binding,mvvm,datatemplate,C#,Wpf,Data Binding,Mvvm,Datatemplate,我目前有以下代码: <DataTemplate DataType="{x:Type vm:SectionViewModel}"> <ScrollViewer> <ItemsControl ItemsSource="{Binding ViewModels}"> </ItemsControl> </ScrollViewer> </DataTemplate> <DataTemp
<DataTemplate DataType="{x:Type vm:SectionViewModel}">
<ScrollViewer>
<ItemsControl ItemsSource="{Binding ViewModels}">
</ItemsControl>
</ScrollViewer>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Name="Left" Grid.Row="0" Grid.Column="0" Content="{Binding Label}"/>
<TextBox Name="Right" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="1" Text="{Binding Value}"/>
</Grid>
</DataTemplate>
绑定到SectionViewModel ItemsControl的ViewModels属性是StringViewModel的列表。我想将每个StringViewModel插入ItemsControl中的某种内容控件中。目前,我只是让每个StringViewModel创建自己的网格,但这会使事情不对齐。我想将这些项插入ItemsControl中的某种内容控件,它不一定是网格,但应该在ItemsControl中。我该怎么做?我也在关注MVVM,使用MVVM灯
编辑:我修改了XAML以反映我当前的设置方式。将数据模板(对于SectionViewModel)更改为使用列表框而不是更通用的控件是最简单的。设置好后,将DataTemplate更改为附加到列表框 不幸的是,如果不进入更复杂的布局,就没有真正简单的方法来设置您所描述的控件。我建议这样设置,如果需要为列绑定到某个宽度,请将其附加到父控件(或者设置一个属性,确定最大宽度,并将它们全部绑定到该宽度)
将数据模板(对于SectionViewModel)更改为使用列表框而不是更通用的控件是最简单的。设置好后,将DataTemplate更改为附加到列表框 不幸的是,如果不进入更复杂的布局,就没有真正简单的方法来设置您所描述的控件。我建议这样设置,如果需要为列绑定到某个宽度,请将其附加到父控件(或者设置一个属性,确定最大宽度,并将它们全部绑定到该宽度)
如果要控制包含模板的宽度,可以使用继承的附加属性:
public class WidthInformation
{
// Use propa snippet to create LabelWidth property with this metadata:
... RegisterAttached("LabelWidth", typeof(double), typeof(WidthInformation), new FrameworkPropertyMetadata
{
Inherits = true
});
}
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<DockPanel>
<Label Content="{Binding Label}" Width="80" />
<TextBox Text="{Binding Value}"/>
</DockPanel>
</DataTemplate>
它将被如此使用:
<DataTemplate DataType="{x:Type vm:SectionViewModel}">
<ScrollViewer>
<ItemsControl ItemsSource="{Binding ViewModels}"
local:WidthInformation.LabelWidth="60" />
</ScrollViewer>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<DockPanel>
<Label Content="{Binding Label}"
Width="{Binding Path=(local:WidthInformation.LabelWidth)"/>
<TextBox Text="{Binding Value}"/>
</DockPanel>
</DataTemplate>
使用DockPanel将导致文本框宽度自动填充剩余空间
另一方面,如果希望两列的相对百分比大小相同,可以对列使用星形大小:
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Label}" />
<TextBox Text="{Binding Value}" Grid.Column="1" />
</DockPanel>
</DataTemplate>
一个非常简单的解决方案是硬编码DockPanel内的宽度,而不是使用附加属性:
public class WidthInformation
{
// Use propa snippet to create LabelWidth property with this metadata:
... RegisterAttached("LabelWidth", typeof(double), typeof(WidthInformation), new FrameworkPropertyMetadata
{
Inherits = true
});
}
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<DockPanel>
<Label Content="{Binding Label}" Width="80" />
<TextBox Text="{Binding Value}"/>
</DockPanel>
</DataTemplate>
最后,如果需要根据标签大小调整宽度,可以使用具有共享大小的网格:
<DataTemplate DataType="{x:Type vm:SectionViewModel}">
<ScrollViewer>
<ItemsControl ItemsSource="{Binding ViewModels}"
Grid.IsSharedSizeScope="true" />
</ScrollViewer>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Label" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Label}" />
<TextBox Text="{Binding Value}" Grid.Column="1" />
</DockPanel>
</DataTemplate>
WPF只是充满了可能性 如果要控制包含模板的宽度,可以使用继承的附加属性:
public class WidthInformation
{
// Use propa snippet to create LabelWidth property with this metadata:
... RegisterAttached("LabelWidth", typeof(double), typeof(WidthInformation), new FrameworkPropertyMetadata
{
Inherits = true
});
}
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<DockPanel>
<Label Content="{Binding Label}" Width="80" />
<TextBox Text="{Binding Value}"/>
</DockPanel>
</DataTemplate>
它将被如此使用:
<DataTemplate DataType="{x:Type vm:SectionViewModel}">
<ScrollViewer>
<ItemsControl ItemsSource="{Binding ViewModels}"
local:WidthInformation.LabelWidth="60" />
</ScrollViewer>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<DockPanel>
<Label Content="{Binding Label}"
Width="{Binding Path=(local:WidthInformation.LabelWidth)"/>
<TextBox Text="{Binding Value}"/>
</DockPanel>
</DataTemplate>
使用DockPanel将导致文本框宽度自动填充剩余空间
另一方面,如果希望两列的相对百分比大小相同,可以对列使用星形大小:
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Label}" />
<TextBox Text="{Binding Value}" Grid.Column="1" />
</DockPanel>
</DataTemplate>
一个非常简单的解决方案是硬编码DockPanel内的宽度,而不是使用附加属性:
public class WidthInformation
{
// Use propa snippet to create LabelWidth property with this metadata:
... RegisterAttached("LabelWidth", typeof(double), typeof(WidthInformation), new FrameworkPropertyMetadata
{
Inherits = true
});
}
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<DockPanel>
<Label Content="{Binding Label}" Width="80" />
<TextBox Text="{Binding Value}"/>
</DockPanel>
</DataTemplate>
最后,如果需要根据标签大小调整宽度,可以使用具有共享大小的网格:
<DataTemplate DataType="{x:Type vm:SectionViewModel}">
<ScrollViewer>
<ItemsControl ItemsSource="{Binding ViewModels}"
Grid.IsSharedSizeScope="true" />
</ScrollViewer>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Label" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Label}" />
<TextBox Text="{Binding Value}" Grid.Column="1" />
</DockPanel>
</DataTemplate>
WPF只是充满了可能性 回答很好(+1),但我会使用继承的附加属性,并将StackPanel更改为DockPanel,以便文本框可以填充可用空间。或者在网格上按比例调整大小。我想我最好在一个实际的答案中详细说明一下。为了简单起见,你的答案会更好:)好答案(+1)但我会使用继承的附加属性,并将StackPanel更改为DockPanel,以便文本框可以填充可用空间。或者在网格上按比例调整大小。我想我最好在一个实际的答案中详细说明一下。为了简单起见,你的答案会更好:)我最终实现了这个完全不同的(使用数据网格),但这基本上就是我想要的。这肯定会有帮助,因为我似乎总是做一些需要这样做的事情。非常感谢!我最终实现了完全不同的(使用DataGrid),但这本质上就是我想要的。这肯定会有帮助,因为我似乎总是做一些需要这样做的事情。非常感谢!