我的ViewModel具有类型为MultipleSelectionInfo的属性,如下所示(为清楚起见,我删除了PropertyChanged相关代码,但我的绑定工作正常):
public abstract class MultipleSelectionInfo
{
// A SelectableObject is made of a bool IsSelected and a string ObjectData
public ObservableCollection<SelectableObject<string>> Items
{ get; set; }
public string Others
{ get; set; }
}
我显示这些属性:
我的XAML看起来像这样:
<DataTemplate x:Key="PrepControl">
<WrapPanel Orientation="Horizontal" HorizontalAlignment="Left">
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Content="{Binding ObjectData}" IsChecked="{Binding IsSelected}" Margin="0,6,8,0"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBox MaxWidth="400" MinWidth="100"
MaxHeight="20" Text="{Binding Others}" IsEnabled="{Binding IsOthersSelected}"
HorizontalAlignment="Left"/>
</WrapPanel>
</DataTemplate>
总结一下,我在ItemsControl(水平WrapPanel)中显示MultipleSelectionInfo的项目,然后我显示TextBox。最后,我将整个包装在一个水平的WrapPanel中。
这个问题是由于WrapPanels,TextBox与项目不能很好地对齐。理想情况下,如果我可以在ItemsControl的WrapPanel中添加TextBox,那将解决它。但我无法做到这一点。
有可能吗?我应该怎么做?我很乐意避免以编程方式操纵控件/面板。如果我真的需要,我对MVVM不太熟悉,你会解释一下吗?
答案 0 :(得分:1)
通用方法是创建DataTemplateSelector
通常,如果对同一类型的对象有多个DataTemplate,并且想要提供自己的逻辑以根据每个数据对象的属性选择要应用的DataTemplate,则可以创建DataTemplateSelector
在给定的情况下,我会尝试触发器,它会修改Others
项的ContentTemplate:
<DataTemplate x:Key="PrepControl">
<ItemsControl ItemsSource="{Binding Items}" Grid.Column="1" Name="Lst">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Content="{Binding ObjectData}"
IsChecked="{Binding IsSelected}"
Margin="0,6,8,0">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Style.Triggers>
<Trigger Property="Content" Value="Others">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}" VerticalAlignment="Center"/>
<TextBox Margin="5,0" VerticalAlignment="Center"
MinWidth="50"
IsEnabled="{Binding IsChecked, RelativeSource={RelativeSource AncestorType=CheckBox}}"
Text="{Binding Path=DataContext.Others, ElementName=Lst}"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
<小时/> 通过触发器
选择DataTemplate的变体
<ItemsControl ItemsSource="{Binding Items}" Grid.Column="1" Name="Lst">
<ItemsControl.Resources>
<DataTemplate x:Key="CheckItem">
<CheckBox Content="{Binding ObjectData}"
IsChecked="{Binding IsSelected}"
Margin="0,6,8,0"/>
</DataTemplate>
<DataTemplate x:Key="OthersItem">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected}"
Content="{Binding ObjectData}"
Margin="0,6,8,0"/>
<TextBox Margin="5,0" VerticalAlignment="Center"
MinWidth="50"
IsEnabled="{Binding IsSelected}"
IsHitTestVisible="True"
Text="{Binding Path=DataContext.Others, ElementName=Lst}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding}">
<ContentPresenter.Style>
<Style TargetType="ContentPresenter">
<Setter Property="ContentTemplate" Value="{StaticResource CheckItem}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ObjectData}" Value="Others">
<Setter Property="ContentTemplate" Value="{StaticResource OthersItem}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentPresenter.Style>
</ContentPresenter>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>