我正在使用 ObjectDataProvider 和 DataTemplate 来填充菜单栏中的 MenuItem。(WPF、C#/XAML)请参阅下面的 snipet。
结果:出现顶部菜单项,当我单击它时,环绕菜单项(带有绑定标题文本的菜单项)与指示子项存在的小箭头一起出现,但悬停或单击箭头不会显示子项,它们无法访问。
预期结果:子项可见且行为正常。
片段:
<ObjectDataProvider x:Key="Brokers" ObjectInstance="{x:Static brokers:BrokerManager.Instance}" MethodName="GetBrokers" IsAsynchronous="True" />
<DataTemplate x:Key="BrokerMenuItem" DataType="IBroker">
<MenuItem Header="{Binding Path=Name}">
<MenuItem Header="Connect" />
<MenuItem Header="Disconnect" />
</MenuItem>
</DataTemplate>
<MenuItem Header="Brokers" ItemsSource="{Binding Source={StaticResource Brokers}}" ItemTemplate="{DynamicResource BrokerMenuItem}"/>
Run Code Online (Sandbox Code Playgroud) 我有一个自定义 UserControl,它具有类型为“DataTemplate”的 DependencyProperty“ItemTemplate”。我通过 .LoadContent() 创建了这个 ItemTemplate 的一个实例,分配了 .DataContext 并将其放入一个 ContentControl。我唯一的缺点是 DataTemplate.Triggers 不会被触发。
示例 Xaml 代码:
<Window.Resources>
<DataTemplate x:Key="MyTemplate">
<Label Name="MyLabel" Content="Default"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding}" Value="1">
<Setter TargetName="MyLabel" Property="Content" Value="True" />
</DataTrigger>
<DataTrigger Binding="{Binding}" Value="0">
<Setter TargetName="MyLabel" Property="Content" Value="False" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
<ContentControl x:Name="MyContent" />
Run Code Online (Sandbox Code Playgroud)
后面的示例代码:
private void Window_Loaded(object sender, RoutedEventArgs e) {
var template = FindResource("MyTemplate") as DataTemplate;
var instance = template.LoadContent() as FrameworkElement;
instance.DataContext = "1";
MyContent.Content = instance;
}
Run Code Online (Sandbox Code Playgroud)
输出为“默认”。
ListBox 中使用的相同 DataTemplate 工作正常:
<ListBox x:Name="MyListBox" …Run Code Online (Sandbox Code Playgroud) 我在 XAML DataTemplate 中定义了我自己的类型。
<DataTemplate DataType="{x:Type MyType}">
...
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
现在我想为相同范围内的相同类型再添加一个模板。我将如何选择在具体的 ItemsControl 中使用哪个模板?
背景:
我有 ItemsControl,它根据项目的类型以不同的方式显示不同类型的对象(当然是从一个基类派生的)。所以我为每种类型指定了未命名的数据模板。现在我需要显示相同的数据,但使用新模板(旧模板支持编辑,新模板不支持)。
我在 WPF 中有一个网格,它由沿 2 列的 4 行组成,其中第 1 列包含一个图像控件,第 2 列包含 4 个文本块。问题是,Image 控件将自身大小调整为 Image 大小,并将列表框的条目扩展到过多 [Its in a DataTemplate] 并使所有内容看起来失真。我不想手动设置最大高度/宽度,因为我希望图像将自身大小调整为旁边的 4 个文本块的大小。有任何想法吗?
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Source="{Binding Logo, Converter={StaticResource BSConverter}}" Grid.Row="0" Grid.RowSpan="4"
Grid.Column="0" Stretch="Uniform" SnapsToDevicePixels="True"/>
<TextBlock Text="{Binding Name}" Grid.Row="0" Grid.Column="1"/>
<TextBlock Text="{Binding Author}" Grid.Row="1" Grid.Column="1"/>
<TextBlock Text="{Binding Version}" Grid.Row="2" Grid.Column="1"/>
<TextBlock Text="{Binding Description}" Grid.Row="3" Grid.Column="1"/>
</Grid>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
提前致谢
如果将控件放入 DataTemplate 中,为什么它们的各个状态会复制或反映在 TabControl 中的每个选项卡中?你在一个选项卡中更改它,所有其他选项卡都会反映,这是为什么?!在我看来,TabControl 仅初始化一个模板化的 ContentControl,并且每次单击选项卡都会重新复制其中的整个内容 - 使旧的控件状态保持不变。要明白我的意思,请考虑将其放入您的 XAML-Pad 中:
<TabControl>
<TabControl.ContentTemplate>
<DataTemplate>
<Border>
<TextBox Text="test"/>
</Border>
</DataTemplate>
</TabControl.ContentTemplate>
<TabItem Header="Tab1"/>
<TabItem Header="Tab2"/>
</TabControl>
Run Code Online (Sandbox Code Playgroud)
它将创建一个带有两个模板化选项卡的 TabControl。现在在文本框中输入一些内容并切换到另一个选项卡,输入的文本将保留。现在每个选项卡将具有相同的内容。我没有在 ListBox 或任何其他控件中观察到相同的行为,这使得实际工作非常困难,因为每一点都需要绑定到 ViewModel 才能使其在 TabControl 中可用。当我在 DataTemplate 中使用的扩展器在我的所有选项卡中弹出时,我注意到了这种奇怪的行为,尽管我专门解决了一个问题。作为一种解决方法,我必须将“IsExpanded”绑定到 ViewModel 中的属性,但这样做确实很糟糕。
有人知道这里发生了什么事吗?
<TabControl x:Name="MainTab" SelectedIndex="0"/>
...
Collection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Collection_CollectionChanged);
...
void Collection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
TabItem MyNewItem = new TabItem();
ContentPresenter MyContentPresenter = new ContentPresenter();
MyContentPresenter.ContentTemplate = (DataTemplate)this.FindResource("MyTemplate");
MyContentPresenter.Content = e.NewItems[0];
MyNewItem.Content = MyContentPresenter;
MainTab.Items.Add(MyNewItem ); …Run Code Online (Sandbox Code Playgroud) 我们需要在代码中确定在给定特定数据类型和该元素的情况下,哪个模板将自动应用于绑定元素。
我们并不是在寻找 DataTemplateSelector,因为它用于根据自定义逻辑告诉UI 对于给定对象使用哪个模板。相反,我们询问UI对于给定的数据类型和 UI 元素将使用哪个模板。
换句话说,我们正在寻找基于窗口资源部分中定义的模板应用的任何 WPF,这些模板可以被该窗口上的控件的资源覆盖,可以通过显式设置 DataTemplate 或直接在该元素上提供 DataTemplateSelector。
另外,我们尝试了 SelectTemplate 的默认实现,但它返回 null,所以我们也不能走这条路。
测试将询问 UI 中任何位置没有定义数据模板或选择器的元素“您将如何显示该值?” 希望它会返回一个包含 TextBlock 定义的 DataTemplate,其中文本属性设置为该对象上的 ToString 方法,这是在未定义任何其他内容时默认显示的内容。
我有一个绑定到项目列表的 ItemsControl。这些项目具有名称和值属性。value 属性属于 Object 类型,以允许使用不同的数据类型。为了正确显示 value 属性,我将 ContentPresenter 与我可能使用的每种数据类型的数据模板一起使用。
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Name}"/>
<GridSplitter Width="1"
Grid.RowSpan="4" Grid.Column="1"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
<ContentPresenter Grid.Column="2" Content="{Binding Value}">
<ContentPresenter.Resources>
<DataTemplate DataType="{x:Type System:String}">
<TextBox Text="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
BorderThickness="0"/>
</DataTemplate>
<DataTemplate DataType="{x:Type System:Int32}">
<TextBox Text="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
TextAlignment="Right"
BorderThickness="0"/>
</DataTemplate>
<DataTemplate DataType="{x:Type System:Double}">
<TextBox Text="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
TextAlignment="Right"
BorderThickness="0"/>
</DataTemplate>
<DataTemplate DataType="{x:Type System:Boolean}">
<CheckBox IsChecked="{Binding Path=Content, RelativeSource={RelativeSource …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Window 的示例代码在 UWP 中实现ListView。
<ListView.GroupStyle>
<GroupStyle >
<GroupStyle.HeaderTemplate>
<DataTemplate x:DataType="data:GroupInfoList">
<TextBlock Text="{x:Bind Key}"
Style="{ThemeResource TitleTextBlockStyle}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
Run Code Online (Sandbox Code Playgroud)
线——
DataTemplate x:DataType="data:GroupInfoList"
给我错误,如左图所示,创建模型时,我想以不同的方式创建它们。它说
名称空间前缀“data”未定义。
它是我需要包含的命名空间吗?
我有一个带有单个特定选项卡的 TabControl 和一个绑定到一组 VM 的集合,使用不同的用户控件。为此,我使用在控件资源中定义的 CompositeCollection 和 DataTemplates,根据 VM 类型(充当 ContentTemplate)选择正确的用户控件。
我还设置了一个 ItemTemplate 来定义带有绑定的选项卡项的名称,但它没有在资源中定义,因为我猜它会与“ContentTemplate”冲突。
它工作正常,但我看到跟踪到以下错误:
System.Windows.Data 错误:26:ItemTemplate 和 ItemTemplateSelector 对于已经属于 ItemsControl 的容器类型的项目被忽略;类型='标签项'
看起来 ContentTemplate 和 ItemTemplate 之间存在一些冲突,但我不知道如何解决?
代码如下:
<TabControl HorizontalAlignment="Left" Height="300" Width="500">
<TabControl.Resources>
<CollectionViewSource x:Key="personCollection" Source="{Binding Persons}" />
<DataTemplate DataType="{x:Type viewModel:Main}">
<local:MainView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:Person}">
<local:PersonView />
</DataTemplate>
</TabControl.Resources>
<TabControl.ItemsSource>
<CompositeCollection>
<TabItem Header="General" Content="{Binding }"/>
<CollectionContainer Collection="{Binding Source={StaticResource personCollection}}" />
</CompositeCollection>
</TabControl.ItemsSource>
<TabControl.ItemTemplate>
<DataTemplate DataType="viewModel:Person">
<TextBlock Text="{Binding FirstName}" />
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
Run Code Online (Sandbox Code Playgroud) 我想知道是否有办法获取对 Xamarin.Forms 中 ListView 中 DataTemplate 内视图的引用。假设我有这个 xaml:
<ListView x:Name="ProductList" ItemsSource="{Binding Products}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="#eee" x:Name="ProductStackLayout"
Orientation="Vertical" Padding="5" Tapped="ListItemTapped">
<Label Text="{Binding Name}"
Style="{DynamicResource ProductPropertiesStyle}"/>
<Label Text="{Binding Notes}" IsVisible="{Binding HasNotes}"
Style="{DynamicResource NotesStyle}"
/>
<Label Text="{Binding Date}"
Style="{DynamicResource DateStyle}"
/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Run Code Online (Sandbox Code Playgroud)
我希望能够在 ListView 的每一行中获取对名为“ProductStackLayout”的 StackLayout 的引用。我需要在页面出现时执行此操作,以动态操作其内容(对于数据绑定无法实现的某些内容),因此我无法利用在源自 DataTemplate 中的元素的事件处理程序中传递的视图引用本身就像 ItemTapped 或类似的。
据我所知,在 WPF 或 UWP 中,可以在 VisualTreeHelper 类的帮助下实现类似的功能,但我不相信 Xamarin.Forms 中存在与此类等效的类。
datatemplate ×10
wpf ×8
xaml ×5
c# ×4
binding ×1
children ×1
code-behind ×1
datatrigger ×1
grid ×1
menuitem ×1
silverlight ×1
tabcontrol ×1
uwp ×1