我想数据绑定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) 我有一个我想要使用的DataTemplate FrameworkElement.FindResource().为此,我需要在数据模板上有一个键.
问题是x:key和分配数据类型是互斥的.(参考)
因此,一旦我为我的模板设置了DataType,我如何找到Key值?是否有一些公式将DataTemplate转换为Key的字符串?
我想构建一个通用/可重用的模式对话框,我可以在我们的WPF(MVVM) - WCF LOB应用程序中使用它.
我有一个视图和相关的ViewModel,我想使用对话框显示.Views和ViewModel之间的绑定是使用以类型为目标的DataTemplates完成的.
以下是我能够起草的一些要求:
做这个的最好方式是什么?
在下面的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)
但是,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) 这是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,所以这不是我想要的.
有什么建议?
我已经修改了我的问题,因为它在尝试时已经改变了焦点.我把问题缩小到以下......
我尝试将TreeView的选定项绑定到StackPanel(或其他一些可以容纳用户控件的容器).然后,此容器将显示UserControl,具体取决于所选项目的类型.
这是StackPanel的xaml(树视图和stackpanel都在同一个窗口中==>不同的网格列)
<StackPanel Grid.Column="2" MinWidth="500" DataContext="{Binding ElementName=myTree, Path=SelectedItem, Mode=OneWay}">
<StackPanel.Resources>
<DataTemplate DataType="{x:Type mvTypes:MyTypeA}">
<controls:UserControlA DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type mvTypes:MyTypeB}">
<controls:UserControlB DataContext="{Binding}" />
</DataTemplate>
</StackPanel.Resources>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
当我将用户控件直接放在stackpanel下(而不是在资源中)时,它会将所选对象显示为datacontext.同上,如果我在其中放置一个TextBox,它将显示所选项目的正确类型.
<TextBox Name="textBox1" Text="{Binding}" />
Run Code Online (Sandbox Code Playgroud)
出于某种原因,将其放在DataTemplate中(即使不设置DataType)也不会显示任何内容.
任何sugestions.我想也许StackPanel可能不适合这个,虽然我似乎找不到其他适合像这样的容器的控件.
提前致谢.
我有一个数据模板中的WPF ComboBox(列表框中的很多组合框),我想处理输入按钮.如果它是一个按钮会很容易 - 我会使用Command + Relative绑定路径等.不幸的是,我不知道如何使用Command处理按键或如何从模板设置事件处理程序.有什么建议?
我试图创建一个WPF应用程序,它将作为一个内的用户控制DataTemplate的ListBoxItem.用户用4 TextBlock秒控制网格.此控件还包含其他形状和图像,用于视觉辅助比任何东西,所以为了清楚起见,我在这个问题的代码中省略了它们.
当我在mainwindow.xaml上删除用户控件时,我可以看到控件,正确绑定的字段指向数据源中的第一条记录.我想要做的是在数据库中的每个记录的列表框或包装面板中重复使用此控件.
任何人都可以向我提供如何将用户控件呈现为控件/其他面板DataTemplate内的指针或示例ListBox.
到目前为止,我已经尝试了以下但无济于事:提前感谢任何提示.
<!--within Window.Resource -->
<DataTemplate x:Key="myActivity">
<local:ucActivityItm /> <!--usercontrol -->
</DataTemplate>
<!-- Listbox within the window -->
<ListBox HorizontalAlignment="Stretch" ItemTemplate="{DynamicResource myActivity}" VerticalAlignment="Stretch">
<ListBoxItem>
<!-- control also added for testing to ensure it rendered out-->
<local:ucActivityItm />
</ListBoxItem>
</ListBox>
Run Code Online (Sandbox Code Playgroud) 我需要以不同方式设置列表视图的第一个和最后一个项目的样式.为此,我开始基于该答案开发解决方案:在WPF项目控件中为最后一项使用不同的模板
基本上,我有一个自定义的ItemsTemplateSelector,它根据列表视图项中的项索引决定要应用的模板(下面的代码).
它正常工作,除了当列表更新(添加或删除项目)时,模板不会再次被选中(例如,最初,SingleItemTemplate被选中,因为有一个项目.当我添加一个项目到列表,第一项的模板没有切换到FirstItemTemplate).如何强制所有项目的模板选择?
public class FirstLastTemplateSelector : DataTemplateSelector
{
public DataTemplate DefaultTemplate { get; set; }
public DataTemplate FirstItemTemplate { get; set; }
public DataTemplate LastItemTemplate { get; set; }
public DataTemplate SingleItemTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
ListView lv = VisualTreeHelperEx.FindParentOfType<ListView>(container);
if (lv != null)
{
if (lv.Items.Count == 1)
{
return SingleItemTemplate;
}
int i = lv.Items.IndexOf(item);
if (i == 0)
{
return FirstItemTemplate;
}
else if (i == lv.Items.Count …Run Code Online (Sandbox Code Playgroud) 我正在尝试找出在MVVM中耦合我的Views和ViewModel的最佳方法,并且我已经使用类型化的 DataTemplates 确定了ViewModel优先方法,如本文和本答案中所述.我正在使用Prism并拥有多个具有自己的项目/类库的模块.
我的问题是:我的DataTemplates在我的解决方案中应该在哪里?
App.Current.MainWindow.Resources.MergedDictionaries?我希望这足以描述我正在尝试做的事情.
更新:查看所选答案的评论.
datatemplate ×10
wpf ×10
itemscontrol ×3
xaml ×3
mvvm ×2
data-binding ×1
listview ×1
modal-dialog ×1
panel ×1
styles ×1
wpf-controls ×1