WPF - 如何将文本框添加到包含ItemsControl的项目的面板

时间:2016-06-15 07:30:07

标签: c# wpf mvvm datatemplate itemscontrol

我的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; }
}

我显示这些属性:

TextBox pushed to the bottom TextBox pushed to the right

我的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不太熟悉,你会解释一下吗?

以下是我期望实现的目标: Expected display 1 Expected display 2

1 个答案:

答案 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>