标签: itemscontrol

根据子对象类型选择DataTemplate

我想数据绑定ItemsCollection,但我想渲染通过集合项上的属性到达的子对象,而不是渲染集合项.

更具体一点:这将是游戏的2D地图查看器(虽然在当前状态下它还不是2D).余数据绑定一个ItemsControl到一个ObservableCollection <广场>,其中方形有一个属性称为地形(类型地形的).地形是一个基类,有各种后代.

我想要的是ItemsControl从每个集合元素渲染Terrain属性,而不是集合元素本身.

我已经可以完成这项工作,但有一些不必要的开销.我想知道是否有一种很好的方法来消除不必要的开销.

我目前拥有以下课程(简化):

public class Terrain {}
public class Dirt : Terrain {}
public class SteelPlate : Terrain {}
public class Square
{
    public Square(Terrain terrain)
    {
        Terrain = terrain;
    }
    public Terrain Terrain { get; private set; }
    // additional properties not relevant here
}
Run Code Online (Sandbox Code Playgroud)

还有一个名为MapView的UserControl,包含以下内容:

<UserControl.Resources>
    <DataTemplate DataType="{x:Type TerrainDataModels:Square}">
        <ContentControl Content="{Binding Path=Terrain}"/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type TerrainDataModels:Dirt}">
        <Canvas Width="40" Height="40" Background="Tan"/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type TerrainDataModels:SteelPlate}">
        <Canvas Width="40" Height="40" Background="Silver"/>
    </DataTemplate>
</UserControl.Resources>
<ItemsControl ItemsSource="{Binding}"/>
Run Code Online (Sandbox Code Playgroud)

鉴于此代码,如果我这样做:

mapView.DataContext = …
Run Code Online (Sandbox Code Playgroud)

wpf datatemplate itemscontrol

11
推荐指数
1
解决办法
1万
查看次数

ItemsControl拖放

我有一个带有DataTemplate的ItemsControl,它绑定到整数的ObservableCollection.

<ItemsControl Name="DimsContainer" ItemTemplate="{StaticResource DimensionsTemplate}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
   </ItemsControl.ItemsPanel>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)

并在Windows资源中:

<Window.Resources>
    <DataTemplate x:Key="DimensionsTemplate" >
        <TextBlock Text="{Binding}"
                       Padding="5"
                       VerticalAlignment="Center"
                       FontSize="32"/>
    </DataTemplate>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)

我正在尝试实现在ItemsControl中拖放项目的能力(即能够重新排序整数).有没有人有一个如何做到这一点的简单例子?我连接了PreviewMouseMove,DragEnter和Drop事件.问题是我无法弄清楚如何确定拖动哪个项目以及拖动它的位置.似乎整个ItemsControl都被传递到事件中.

c# wpf drag-and-drop itemscontrol

11
推荐指数
1
解决办法
9232
查看次数

DataTemplate中的样式是否仅应用于ItemsControl中的最后一项?

在下面的XAML中,我有一个ItemsControl,它有三个DataObjects.
我使用DataTemplate将DataObjects显示为带有"X"的按钮.
Button使用样式设置其内容.

如果Setter.Value为"X",一切都很棒!
但是,如果我将Setter.Value更改为TextProperty为"X"的TextBlock,则X仅出现在最后一个Button(第三个DataObject)上,前两个Buttons为空.

这是一个错误,还是任何人都能解释为什么会这样?

注1)这是一个人为的例子来隔离遇到的问题.
注2)我已将两个Setter.Value选项放在代码中,这样您只需将其中一个注释掉即可重现成功和不成功的情况.
注3)看来,这个问题特定于'内容'属性的Setters.如果我使用Setter作为Background属性,它将正确应用于所有DataObjects.

<Grid>
    <Grid.Resources>
        <Style x:Key="myButtonStyle" TargetType="{x:Type Button}">
            <Setter Property="Content">
                <!--<Setter.Value>X</Setter.Value>-->
                <Setter.Value><TextBlock Text="X" /></Setter.Value>
            </Setter>
            <Setter Property="Background">
                <Setter.Value>
                    <SolidColorBrush Color="Red" />
                </Setter.Value>
            </Setter>
        </Style>
    </Grid.Resources>
    <ItemsControl>
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type DataObject}">
                <Button Height="24" Width="24" Style="{StaticResource myButtonStyle}" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.Items>
            <DataObject />
            <DataObject />
            <DataObject />
        </ItemsControl.Items>
    </ItemsControl>
</Grid>
Run Code Online (Sandbox Code Playgroud)

解:

不幸的是,当Content被设置为TextBlock而不是直接文本的控件时,我仍然无法解释为什么'Content'Setter无法处理除最后一个DataObject之外的所有DataObject.

但是,Dmitry建议使用"ContentTemplate"而不是"Content"是一种非常可接受的解决方法,仍然允许使用可重复使用的样式.

<Grid>
    <Grid.Resources>
        <DataTemplate x:Key="textBlockWithX">
            <TextBlock Text="X" />
        </DataTemplate>
        <Style x:Key="myButtonStyle" TargetType="{x:Type Button}">
            <Setter Property="ContentTemplate" Value="{StaticResource textBlockWithX}" />
        </Style>
    </Grid.Resources>
    <ItemsControl> …
Run Code Online (Sandbox Code Playgroud)

wpf xaml styles datatemplate itemscontrol

11
推荐指数
2
解决办法
1万
查看次数

水平显示ItemsControl内的项目集合

这是XAML标记:

        <ScrollViewer Grid.Column="1" Grid.Row="2" HorizontalScrollBarVisibility="Disabled" Width="990">
            <StackPanel Margin="50 0 0 40">                    
                <ItemsControl x:Name="streamList" ItemsSource="{Binding StreamInformations}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Margin="10" Orientation="Horizontal" >
                                <StackPanel Orientation="Horizontal">
                                    <Image Source="{Binding ImageUrl}" Height="60" />
                                    <StackPanel Margin="10 0 0 0" VerticalAlignment="Center">
                                        <TextBlock Foreground="Black" Text="{Binding ChannelName}" FontSize="12" />
                                        <TextBlock Foreground="#999" Text="{Binding PlayerName}" FontSize="10" />
                                        <TextBlock Foreground="#999" Text="{Binding ViewCount}" FontSize="10" />
                                    </StackPanel>                                        
                                </StackPanel>                                   
                            </StackPanel>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>
        </ScrollViewer>
Run Code Online (Sandbox Code Playgroud)

这就是它的样子:

在此输入图像描述

我希望这些项目水平显示并在到达StackPanel边缘时向下流动.

目前看来,我的DataContext集合中的每个项目都在创建自己的StackPanel,所以这不是我想要的.

有什么建议?

wpf xaml panel datatemplate itemscontrol

11
推荐指数
1
解决办法
1万
查看次数

为什么ItemsControl的容器的Parent属性返回null而不是它所在的Panel?

这个让我难过.我们有一个自定义ItemsControl,它既使用自定义容器,也使用自定义面板作为ItemsHost.现在,该面板有一些容器需要用于渲染目的的度量标准.由于它们是可视化树中面板的直接子节点,因此您认为容器的Parent属性将返回面板,但它不会!

我已经在标准ListBox上使用Snoop确认了这个确切的事情,所以这不是我们的代码所独有的,但显然是ItemsControls的所有容器.

现在我知道我可以使用VisualTreeHelper来获取可视化父级(这是我需要的),但为什么父级不是面板?

如果参数是面板只是Visual Tree的一部分而Parent是为逻辑树保留的,那么父节点不是ItemsControl吗?

如果容器中的参数也是ItemsControl的可视树而不是逻辑树的一部分,那么为什么容器中托管的内容会将容器作为其Parent属性返回?

这意味着如果您从数据项中走出逻辑树,则停在容器上,这可以解释为什么我们从容器到面板的绑定没有按预期工作.(我相信绑定是基于逻辑层次结构而不是视觉层次结构,但我必须进行测试才能确定.)

wpf visualtreehelper parent itemscontrol

11
推荐指数
2
解决办法
1335
查看次数

ItemsControl缺少垂直滚动条

我有以下ItemsControl完美包装项目,但它没有垂直滚动条,所以我看不到包装的项目.如何显示滚动条?

    <ItemsControl x:Name="tStack" Grid.Column="0" Grid.Row="1"
                  ItemsSource="{Binding Shows.View}"
                  HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                  BorderThickness="0.5">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Horizontal" HorizontalAlignment="Left"
                           VerticalAlignment="Top"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Viewbox HorizontalAlignment="Left"  Height="250">
                    <Controls1:MyShowsUserControl Padding="10"/>
                </Viewbox>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
Run Code Online (Sandbox Code Playgroud)

wpf xaml scroll itemscontrol

11
推荐指数
2
解决办法
1万
查看次数

ItemsControl按钮单击命令

我现在需要一些快速帮助,这对我来说是一个障碍.我有Button,ItemsControl我需要在按钮点击上执行一些任务.我尝试添加CommandButtonI temsControl DataTemplate但它不起作用.任何人都可以建议如何进一步.

<UserControl.Resources>
    <DataTemplate x:key="mytask">
        <TextBox Grid.Row="5" Grid.Column="2" Text="{Binding Path=PriorNote}" Grid.ColumnSpan="7"  VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,5" Width="505" Foreground="Black"/>
        <StatusBarItem Grid.Row="2" Grid.Column="8" Margin="8,7,7,8" Grid.RowSpan="2">
        <Button x:Name="DetailsButton" Command="{Binding CommandDetailsButtonClick}">
    </DataTemplate>
</UserControl.Resources>

<Grid>
    <ItemsControl Grid.Row="1" 
                  ItemsSource="{Binding ListStpRules}" 
                  ItemTemplate="{StaticResource myTaskTemplate}" Background="Black"
                  AlternationCount="2" >
    </ItemsControl>
</Grid>
Run Code Online (Sandbox Code Playgroud)

在ViewModel中,我已经为Command实现了代码.它不起作用.请为我提出任何解决方案以便继续进行

wpf user-controls itemscontrol mvvm wpf-controls

10
推荐指数
2
解决办法
8292
查看次数

滚动到虚拟化ItemsControl的元素

我有一个ItemsControl在a中显示其项目ScrollViewer,并进行虚拟化.我试图将其滚动ScrollViewer到它包含的(屏幕外,因此虚拟化)项目.但是,由于项目是虚拟化的,因此屏幕上并不存在并且没有位置(IIUC).

我已尝试BringIntoView过子元素,但它不会滚动到视图中.我也尝试手动用做它TransformToAncestor,TransformBoundsScrollToVerticalOffset,但TransformToAncestor不会返回(我猜是因为虚拟化的同时,因为它没有位置,但我没有这方面的证明)和代码它从未执行后.

是否可以滚动到虚拟化的项目ItemsControl?如果是这样,怎么样?

c# wpf itemscontrol virtualizingstackpanel

10
推荐指数
3
解决办法
7795
查看次数

在水平ItemsControl中滚动

如何添加滚动条,让我滚动水平显示的项目?

   <ItemsControl ItemsSource="{Binding Data, ElementName=myWindows}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel Orientation="Horizontal">
                </VirtualizingStackPanel>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemContainerStyle>
            <Style TargetType="FrameworkElement" >
                <Setter Property="Margin" Value="10,0,10,0"></Setter>
            </Style>
        </ItemsControl.ItemContainerStyle>
    </ItemsControl>
Run Code Online (Sandbox Code Playgroud)

wpf itemscontrol horizontal-scrolling

10
推荐指数
1
解决办法
4172
查看次数

更新ObservableCollection中的项目时更新ItemsControl

问题:

  • 您在视图中声明ItemsControl(或从中派生的控件ItemsControl).
  • 您将ItemsControl.ItemsSource属性绑定到ObservableCollectionViewModel中的a.
  • 当项目被添加到/从中删除时,您的视图会按预期更新ObservableCollection.
  • 但是,当您更改项目中的项目的属性时,视图不会更新ObservableCollection.

背景:

这似乎是许多WPF开发人员遇到的常见问题.有人问过几次:

项目更改时通知ObservableCollection

ObservableCollection没有注意到它中的Item何时发生变化(即使使用INotifyPropertyChanged)

ObservableCollection和Item PropertyChanged

我的实施:

当Item更改时,我尝试在Notify ObservableCollection中实现接受的解决方案.基本思想是PropertyChanged在MainWindowViewModel中为每个项目连接一个处理程序ObservableCollection.更改项目的属性时,将调用事件处理程序,并以某种方式更新视图.

我无法让实现工作.这是我的实施.

的ViewModels:

class ViewModelBase : INotifyPropertyChanged 
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string propertyName = "")
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
Run Code Online (Sandbox Code Playgroud)

项目视图模型:

class EmployeeViewModel : ViewModelBase
{
    private int _age;
    private string _name;

    public int Age 
    { …
Run Code Online (Sandbox Code Playgroud)

c# wpf itemscontrol observablecollection mvvm

10
推荐指数
1
解决办法
1万
查看次数