我正在使用以下代码动态添加列到我的GridView:
public void AddGridViewColumns()
{
GridView view = (GridView)_myListView.View;
GridViewColumn column = BuildGridViewColumn(1);
view.Columns.Add(column);
}
public virtual GridViewColumn BuildGridViewColumn(int blockIndex)
{
string templateXaml = string.Format(
@"<DataTemplate
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
xmlns:local=""clr-namespace:Pse.MyTest;assembly=MyTest"">
<DataTemplate.Resources>
<local:BlockToBrushConverter
x:Key=""_blockToBrushConverter"" />
</DataTemplate.Resources>
<TextBlock
Style=""{{StaticResource _gridViewCenterItemStyle}}""
Text=""{{Binding Path=Block{0}.ConditionLabel}}""
Foreground=""{{Binding Path=Block{0}, Converter={{StaticResource _blockToBrushConverter}}}}"" />
</DataTemplate>",
blockIndex);
System.Diagnostics.Debug.Print(templateXaml);
GridViewColumn column = new GridViewColumn();
column.Header = string.Format("Block {0}", blockIndex);
column.CellTemplate = (DataTemplate)XamlReader.Parse(templateXaml);
return column;
}
Run Code Online (Sandbox Code Playgroud)
Debug.Print导致:
<DataTemplate
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Pse.MyTest;assembly=MyTest">
<DataTemplate.Resources>
<local:BlockToBrushConverter
x:Key="_blockToBrushConverter" />
</DataTemplate.Resources>
<TextBlock
Style="{StaticResource _gridViewCenterItemStyle}"
Text="{Binding Path=Block1.ConditionLabel}"
Foreground="{Binding Path=Block1, …Run Code Online (Sandbox Code Playgroud) 我已经修改了我的问题,因为它在尝试时已经改变了焦点.我把问题缩小到以下......
我尝试将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可能不适合这个,虽然我似乎找不到其他适合像这样的容器的控件.
提前致谢.
我在后面的代码中手动添加TreeViewItems,并希望使用DataTemplate来显示它们,但无法弄清楚如何.我希望做这样的事情,但项目显示为空标题.我究竟做错了什么?
XAML
<Window x:Class="TreeTest.WindowTree"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WindowTree" Height="300" Width="300">
<Grid>
<TreeView Name="_treeView">
<TreeView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=Age}" />
</StackPanel>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
代码背后
using System.Windows;
using System.Windows.Controls;
namespace TreeTest
{
public partial class WindowTree : Window
{
public WindowTree()
{
InitializeComponent();
TreeViewItem itemBob = new TreeViewItem();
itemBob.DataContext = new Person() { Name = "Bob", Age = 34 };
TreeViewItem itemSally = new TreeViewItem();
itemSally.DataContext = new Person() { Name = "Sally", Age …Run Code Online (Sandbox Code Playgroud) 我有一个ListBox显示员工的数据,如姓名,部门照片,徽章编号等.员工可能有不同的类型,如经理,员工,志愿者.我有3个独立的数据模板 - 每种类型一个.所有这些模板显示的数据基本相同,但呈现的方式不同.
根据登录应用程序图片的用户,徽章编号等可以显示也可以不显示.所以我有布尔属性 - CanSeePhotos,CanSeeBadgeNumbers等.所以如果CanSeePhotos == false,所有数据模板都应该隐藏照片.
我的问题是,如何在我的数据模板中使用这些布尔属性来切换相应项目的可见性?当我从TemplateSelector返回参数时,有没有办法将参数传递给数据模板?
谢谢!
编辑:跟随雷的想法我最终做到了这一点:
Visibility="{Binding Source={x:Static local:Global.CanSeePhoto}, Converter={StaticResource BooleanToVisibilityConverter}}"
Run Code Online (Sandbox Code Playgroud) 我有一个DataTemplate:
<DataTemplate x:Key="myTemplate">
...
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
我想用它作为ContentTemplate一个ContentPresenter:
<ContentPresenter Content="{Binding X}">
<ContentPresenter.ContentTemplate >
<!-- ????? what goes here ????-->
</ContentPresenter.ContentTemplate>
</ContentPresenter>
Run Code Online (Sandbox Code Playgroud)
我如何可以使用预定义DataTemplate的我ContentPresenter?
为什么以下隐含DataTemplate不起作用?只有注释的内联才DataTemplate有效.
注意:如果我删除了两个DataTemplates,我会看到ProductListView完整类型名称的字符串表示.
<Window.Resources>
<DataTemplate DataType="vm:ProductListViewModel">
<v:ProductListView/>
</DataTemplate>
</Window.Resources>
<TabControl ItemsSource="{Binding Tabs}" TabStripPlacement="Left">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Key}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Value}">
<!--ContentPresenter.ContentTemplate>
<DataTemplate DataType="vm:ProductListViewModel">
<v:ProductListView/>
</DataTemplate>
</ContentPresenter.ContentTemplate-->
</ContentPresenter>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
Run Code Online (Sandbox Code Playgroud) 我想在不同页面是TabItems的应用程序中使用MVVM.
为此,我使用了一个可观察的视图模型(Items)集合,并将其绑定到tabcontrols ItemSource.
对于每个视图模型,我创建了一个单独的数据模板来呈现正确的视图,如下所示:
<DataTemplate DataType="{x:Type baseVm:AViewModel}">
<baseVw:AView />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
要在选项卡的标题中显示正确的名称,我创建了另一个数据模板,以应用于每个选项卡控件的元素:
<DataTemplate x:Key="ViewModelTabTemplate">
<DockPanel>
<ContentPresenter Content="{Binding Path=Name}"/>
</DockPanel>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
选项卡控件如下所示:
<TabControl x:Name="myTabControl"
ItemsSource="{Binding Items}"
ItemTemplate="{DynamicResource ViewModelTabTemplate}">
</TabControl>
Run Code Online (Sandbox Code Playgroud)
我现在要做的是在包含集合的视图模型中启用/禁用选项卡.视图模型的基类包含一个依赖项属性IsEnabled,我想将它绑定到视图.如果我直接在视图中这样做:
IsEnabled="{Binding IsEnabled, FallbackValue=true}"
Run Code Online (Sandbox Code Playgroud)
当我将IsEnabled属性设置为false时,标签页的内容被禁用.但我真正想要的是也禁用tabpage的标签而不仅仅是内容.
谢谢你的帮助!
我正在尝试找出在MVVM中耦合我的Views和ViewModel的最佳方法,并且我已经使用类型化的 DataTemplates 确定了ViewModel优先方法,如本文和本答案中所述.我正在使用Prism并拥有多个具有自己的项目/类库的模块.
我的问题是:我的DataTemplates在我的解决方案中应该在哪里?
App.Current.MainWindow.Resources.MergedDictionaries?我希望这足以描述我正在尝试做的事情.
更新:查看所选答案的评论.
我已经声明了以下类型:
public interface ITest { }
public class ClassOne : ITest { }
public class ClassTwo : ITest { }
Run Code Online (Sandbox Code Playgroud)
在我的viewmodel中,我正在声明并初始化以下集合:
public class ViewModel
{
public ObservableCollection<ITest> Coll { get; set; } = new ObservableCollection<ITest>
{
new ClassOne(),
new ClassTwo()
};
}
Run Code Online (Sandbox Code Playgroud)
在我看来,我宣布以下内容 ItemsControl
<ItemsControl ItemsSource="{Binding Coll}">
<ItemsControl.Resources>
<DataTemplate DataType="local:ClassOne">
<Rectangle Width="50" Height="50" Fill="Red" />
</DataTemplate>
<DataTemplate DataType="local:ClassTwo">
<Rectangle Width="50" Height="50" Fill="Blue" />
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
我期待看到的是一个红色方块,后面是一个蓝色方块,而我所看到的是以下内容:
我究竟做错了什么?
我有这个扩展标记
public class NullableExtension : TypeExtension
{
public NullableExtension() {
}
public NullableExtension( string type )
: base(type) {
}
public NullableExtension( Type type )
: base(type) {
}
public override object ProvideValue( IServiceProvider serviceProvider ) {
Type basis = (Type)base.ProvideValue( serviceProvider );
return typeof(Nullable<>).MakeGenericType( basis );
}
}
Run Code Online (Sandbox Code Playgroud)
它旨在提供其他类型的可空版本.当在"普通"XAML中使用时,它按预期工作.例如,如
<SomeControl DataContext="{My:Nullable System:Int32}"/>
Run Code Online (Sandbox Code Playgroud)
(假设My是为保存扩展的C#名称空间定义的XML名称空间,对于System来说类似).控件的数据上下文设置为System.Typefor,Nullable<int>如我所料.
但是,当我使用此扩展来尝试设置类似的DataType属性时DataTemplate
<DataTemplate DataType="{My:Nullable System:Int32}">
<TextBlock ... />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
编译器告诉我的是
字典的键不能是'System.Windows.Controls.Primitives.TextBlock'类型.只支持String,TypeExtension和StaticExtension."
和
"类型'NullableExtension'的构造函数没有1个参数.
有人知道为什么只允许这三种方法(甚至不是TypeExtension像我的子类一样)?那时处理XAML有什么特别之处?是否有另一种方法来实现这一点(基于可以为空的类型的数据模板选择)而不诉诸DataTemplateSelector?
datatemplate ×10
wpf ×10
xaml ×5
mvvm ×3
binding ×1
c# ×1
data-binding ×1
dynamic ×1
itemtemplate ×1
tabcontrol ×1
treeview ×1