【问题标题】:Items added to ItemsControl not using ItemTemplate添加到 ItemsControl 的项目不使用 ItemTemplate
【发布时间】:2015-09-18 08:49:47
【问题描述】:

我对 wpf 比较陌生,所以对于任何不良的编码习惯,我提前道歉。

我正在尝试创建一个仪表板应用程序,用户可以通过添加不同的控件(表格、图表等)来自定义它并移动它们/调整它们的大小。

我最初使用 Canvas 来绘制我的控件,并且可以进行移动和调整大小。由于需要动态内容,我转而使用 ItemsControl,如下所示:

<ItemsControl Name="dashboardCanvas" ItemsSource="{Binding Path=CanvasContents}" Grid.Row="1">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.Resources>
            <ControlTemplate x:Key="MoveThumbTemplate" TargetType="{x:Type local:MoveThumb}">
                <Rectangle Fill="Transparent"/>
            </ControlTemplate>
            <ControlTemplate x:Key="ResizeDecoratorTemplate" TargetType="Control">
                <Grid>
                    <local:ResizeThumb Height="2" Cursor="SizeNS" Margin="0 -4 0 0" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
                    <local:ResizeThumb Width="2" Cursor="SizeWE" Margin="-4 0 0 0" VerticalAlignment="Stretch" HorizontalAlignment="Left"/>
                    <local:ResizeThumb Width="2" Cursor="SizeWE" Margin="0 0 -4 0" VerticalAlignment="Stretch" HorizontalAlignment="Right"/>
                    <local:ResizeThumb Height="2" Cursor="SizeNS" Margin="0 0 0 -4" VerticalAlignment="Bottom"  HorizontalAlignment="Stretch"/>
                    <local:ResizeThumb Width="7" Height="7" Cursor="SizeNWSE" Margin="-6 -6 0 0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
                    <local:ResizeThumb Width="7" Height="7" Cursor="SizeNESW" Margin="0 -6 -6 0" VerticalAlignment="Top" HorizontalAlignment="Right"/>
                    <local:ResizeThumb Width="7" Height="7" Cursor="SizeNESW" Margin="-6 0 0 -6" VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
                    <local:ResizeThumb Width="7" Height="7" Cursor="SizeNWSE" Margin="0 0 -6 -6" VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
                </Grid>
            </ControlTemplate>
            <ControlTemplate x:Key="DesignerItemTemplate">
                <Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
                    <local:MoveThumb Template="{StaticResource MoveThumbTemplate}" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Cursor="SizeAll"/>
                    <Control Template="{StaticResource ResizeDecoratorTemplate}"/>
                    <ContentPresenter Content="{TemplateBinding ContentControl.Content}"/>
                    <Button Content="x" VerticalAlignment="Top" HorizontalAlignment="Right" Width="10" Height="10" Click="Button_Click"/>
                </Grid>
            </ControlTemplate>
        </ItemsControl.Resources>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
                    <local:MoveThumb Template="{StaticResource MoveThumbTemplate}" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Cursor="SizeAll"/>
                    <Control Template="{StaticResource ResizeDecoratorTemplate}"/>
                    <ContentPresenter Content="{TemplateBinding ContentControl.Content}"/>
                    <Button Content="x" VerticalAlignment="Top" HorizontalAlignment="Right" Width="10" Height="10" Click="Button_Click"/>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="Canvas.Top" Value="{Binding Path=Y}"/>
                <Setter Property="Canvas.Left" Value="{Binding Path=X}"/>
            </Style>
        </ItemsControl.ItemContainerStyle>
    </ItemsControl>

我现在遇到一个问题,我添加到 ItemsControl 的任何控件都没有应用模板。

我看过这个问题:Why Does ItemsControl Not Use My ItemTemplate? 但是我不能将 ItemsControl 继承到我的控件中,因为它们已经从 ContentControls 继承。

这是我的主要控制对象:

class TableControl: DashboardItem
{
    public TableControl()
    {
        Width = 100;
        Height = 100;
        Content = new Ellipse
            {
                Fill = new SolidColorBrush(Colors.Green),
                IsHitTestVisible = false
            };
    }

    public int X
    {
        get
        {
            return 10;
        }
    }

    public int Y
    {
        get
        {
            return 200;
        }
    }
}

此时的DashboardItem 很简单:

class DashboardItem : ContentControl
{

}

在后面的代码中,我有一个 DashboardItems 的 ObservableCollection,ItemsControl 绑定到它。

如何强制将 ItemsControl 模板应用于控件中的所有项目?

【问题讨论】:

    标签: c# .net wpf data-binding


    【解决方案1】:

    眨眼,

    我试了一下你的代码,发现了错误。

    您的代码中有奇怪的混合。 您不能拥有ObservableCollectionContentControl。 使您的对象 DashboardItems ,真正的业务对象(或视图模型对象),可能持有 X 和 Y 属性,但没有 ContentControl 的继承。

    如果您提供 GUI 对象,WPF 似乎并不关心您的模板。

    如果您需要为项目控件的不同项目设置不同的外观,那么您将能够使用
    -a TemplateSelector(用于为给定行选择模板)
    - 或 DataItemTemplate 的 DataType 属性

    祝你好运

    【讨论】:

    • 我已将 DashboardItems 更改为仅包含 X 和 Y 值(没有任何继承),并以椭圆的形式(仅作为占位符)添加到 ItemsControl 的 DataTemplate 中。尽管移动和调整大小不起作用,但它现在正在应用模板。我认为这可能与 dataContexts 有关,但我不知道
    • @Blix,是的,您可以,只是不要更改 Grid 的 Datacontext :
    • 默认情况下,您的 DataTemplate 具有正确的 DataContext:&lt;ItemsControl.ItemTemplate&gt; &lt;DataTemplate&gt; &lt;Grid &gt;。它对我有用。
    • 一切正常显示,但 MoveThumb 和 ResizeThumb 的功能不起作用。 MoveThumb 和 ResizeThumb 都是我项目中的类。模板中控件的数据上下文应该是什么?
    • 不工作?你的意思是不可见......?有什么问题 ?从我在 XAML 代码中看到的内容来看,您没有在 MoveThumb 和 ResizeThumb 中使用 DataBinding,因此数据绑定/数据上下文似乎并不重要
    【解决方案2】:

    只是添加另一个解决方案。正如公认的答案指出的那样,如果您直接使用ItemsControl,则您传入的任何GUI对象都将按原样排列在ItemsPanel上,从而完全绕过您的DataTemplate。 (如果不是 GUI 对象,则首先将其包裹在 ContentPresenter 中。)

    要解决这个问题,您可以创建ItemsControl 的子类,强制始终为您的项目创建一个容器。为此,您可以为 IsItemItsOwnContainerOverride 返回 false。这告诉控件项目必须首先被包装在一个容器中——同样,在ItemsControl的默认实现中是一个简单的ContentPresenter——因此它将始终适用任何给定的ItemTemplate

    这是代码...

    public class EnsureContainerItemsControl : ItemsControl {
    
        protected override bool IsItemItsOwnContainerOverride(object item) {
            return false; // Force the control to always generate a container regardless of what was passed in
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 2014-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多