我们写的是一个非常专业的ItemsControl,实际上ContentPresenter每个'行' 有三个,每个都绑定到一个不同的对象(想想穷人的网格)而不是更常见的一个,比如a ListBox.
现在有一个ListBox如果你没有明确指定一个ItemTemplate或一个ItemTemplateSelector,似乎有一些内部选择器纯粹基于数据类型应用模板.但是,我们ContentPresenter不会接受它们.我们也尝试过将它们ContentControl改为,但这也没有用.
现在我知道我可以简单地写我自己DataTypeTemplateSelector做这个工作,但如果该功能已经"出炉中的"我不知道什么地方认为它有这么多使用ItemsControl的(ListBox,TreeView,ComboBox',DataGrid等),并根据这个MSDN文章...
http://msdn.microsoft.com/en-us/library/ms742521.aspx
......它应该默认工作!但同样,它没有.
这是我们的(伪)代码......
<UserControl.Resources>
<!-- These all work when the relevant items are in a ListBox,
but not with stand-alone ContentPresenters or ContentControls -->
<DataTemplate DataType="local:SomeTypeA">
<TextBlock Text="{Binding Converter={c:DataTypeNameConverter}}" Foreground="Blue" />
</DataTemplate>
<DataTemplate DataType="local::SomeTypeB">
<TextBlock Text="{Binding Converter={c:DataTypeNameConverter}}" Foreground="Purple" />
</DataTemplate>
<DataTemplate DataType="local::SomeTypeC">
<TextBlock Text="{Binding Converter={c:DataTypeNameConverter}}" Foreground="Purple" />
</DataTemplate> …Run Code Online (Sandbox Code Playgroud) wpf datatemplate contentpresenter contentcontrol datatemplateselector
我有一个ContentControl,我想在某些情况下更改它的ContentTemplate.我想在ContentTemplate中加载控件时添加一些值(文本到TextBox).但是,我发现在更改属性ContentTemplate后,直接应用新的ContentTemplate(在加载新模板的所有控件方面).
myContentControl.ContentTemplate = newContentTemplate;
// at this line controls of new template are not loaded!
Run Code Online (Sandbox Code Playgroud)
我通过在该行之后添加此代码进行测试:
var cp = GetVisualChild<ContentPresenter>(myContentControl);
var txt = myContentControl.ContentTemplate.FindName("Path_Cover", cp) as TextBox;
txt.Text = "test";
Run Code Online (Sandbox Code Playgroud)
GetVisualChild
private T GetVisualChild<T>(DependencyObject parent) where T : Visual
{
T child = default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
child = v as T;
if (child == null)
{
child = GetVisualChild<T>(v);
}
if (child != …Run Code Online (Sandbox Code Playgroud) 我希望它ContentTemplate根据中的值而变化DataTrigger.
是的,我考虑使用a DataTemplateSelector,但现在我需要一个DataTrigger或更好的说a MultiDataTrigger.
请看下面的示例应用程序,DataTemplate不会改变:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:WpfApplication1">
<StackPanel>
<CheckBox IsChecked="{Binding BoolProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:Window1}}}" Content="BoolProperty"/>
<ContentControl Content="{Binding BoolProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:Window1}}}">
<ContentControl.ContentTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding BoolProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:Window1}}}" Content="Template 1"/>
</DataTemplate>
</ContentControl.ContentTemplate>
<ContentControl.Resources>
<DataTemplate x:Key="Template2">
<CheckBox IsChecked="{Binding BoolProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:Window1}}}" Content="Template 2"/>
</DataTemplate>
</ContentControl.Resources>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding BoolProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:Window1}}}" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource Template2}"/>
</DataTrigger> …Run Code Online (Sandbox Code Playgroud) 我试图创建一些图表图像,而无需在屏幕上显示这些图表.我已经在这方面工作了很长一段时间并尝试了很多不同的东西,但似乎没有任何工作.如果我首先在窗口中显示图表,代码可以正常工作,但如果我不在窗口中显示它,则位图只是白色,带有黑色边框(不知道为什么).
我尝试在渲染之前将图表添加到边框,并为边框指定绿色borderBrush.在位图中,我看到绿色borderBrush然后是黑色边框和白色背景但没有图表.图表不包含在黑色寄宿生中,所以我不知道它来自哪里.
我已经尝试将图表添加到窗口而不调用window.Show()并再次我得到黑色边框和白色背景.但是,如果我调用window.Show(),则位图包含图表.
我已经使用drawingVisual作为解释试图在这里,同样的结果.
这是代码(不包括将元素添加到边框或窗口):
private static BitmapSource CreateElementScreenshot(FrameworkElement element, int dpi)
{
if (!element.IsMeasureValid)
{
Size size = new Size(element.Width, element.Height);
element.Measure(size);
element.Arrange(new Rect(size));
}
element.UpdateLayout();
var scale = dpi/96.0;
var renderTargetBitmap = new RenderTargetBitmap
(
(int)(scale * element.RenderSize.Width),(int)(scale * element.RenderSize.Height),dpi,dpi,PixelFormats.Default
);
// this is waiting for dispatcher to perform measure, arrange and render passes
element.Dispatcher.Invoke(((Action)(() => renderTargetBitmap.Render(element))), DispatcherPriority.Render);
return renderTargetBitmap;
}
Run Code Online (Sandbox Code Playgroud)
注意:图表是ContentControl.
无论如何我可以让图表呈现而不先在窗口中显示它吗?
我需要禁用TextBox的标准ContextMenu.我创建了一个新的WPF项目并添加了以下内容:
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ContentControl>
<ContentControl.ContentTemplate>
<DataTemplate>
<TextBox ContextMenu="{x:Null}" VerticalAlignment="Top" HorizontalAlignment="Left" Width="50"></TextBox>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
但这就是我得到的:

以下代码工作正常:
<Grid>
<TextBox ContextMenu="{x:Null}" VerticalAlignment="Top" HorizontalAlignment="Left" Width="50"></TextBox>
</Grid>
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
更新.
根据接受的答案,我创建了一个派生自TextBox的类,以便能够显示父母ContextMenu.
public class TextBoxNoMenu: TextBox
{
public TextBoxNoMenu()
{
ContextMenu = null;
}
}
Run Code Online (Sandbox Code Playgroud) 默认情况下,当您使用"ActivateItem(new Control());"时 例如,您的控件被加载到名为ActiveItem的ContentControl中..如果我的页面上有多个内容控件,我将如何在其中加载控件,同时保留使用能够将控件加载到活动项控件的默认功能的功能.
例如,我希望将登录控件加载到Login ContentControl中,当用户成功登录时,我希望将新控件加载到ActiveItem ContentControl中.
Thanx提前.
将对象分配给Content控件时,它将实现适合该已分配对象的Visual.有没有一种程序化的方法来实现相同的结果?我想在WPF中使用一个对象调用一个函数并返回一个Visual,其中在生成Visual时应用相同的逻辑,就像您已将对象提供给Content控件实例一样.
例如,如果我有一个POCO对象并将其分配给Content控件并且恰好定义了相应的DataTemplate,那么它将实现该模板以创建Visual.我希望我的代码能够获取POCO对象并从WPF中获取Visual.
有任何想法吗?
我有一个令人讨厌的问题......也许有人可以(请!)帮忙.我正在使用一个模型,它具有类型和枚举属性,应该为枚举中的每个选定类型保存UI模型:让我们将它们定义为:
class ViewModel
{
Types selectedType{get;set;}
UiModelBase editedModel{get;set;}
}
Run Code Online (Sandbox Code Playgroud)
我希望每次更改selectedType时都有一个使用datatemplateselector来更改视图的内容控件.
<ListBox x:Name="RuleTypeList" ItemsSource="{Binding Source={StaticResource Types}}" SelectedItem="{Binding Path=selectedType}"/>
<!--Content control-->
<ContentControl ContentTemplateSelector="{StaticResource ruleEditTemplateSelector}"
Content="{Binding SelectedItem, ElementName=RuleTypeList}"/>
Run Code Online (Sandbox Code Playgroud)
问题:我创建的DataTemplates由ruleEditTemplateSelector返回,DataContext是Type(同意)但我需要访问editedModel来创建我的DataTemplate ...我不知道如何处理它
提前致谢!
我正在试图弄清楚如何让我ContentControl正确地水平滚动(此刻垂直方向).通过正确我的意思是我希望看到内容伸展(无限扩展),同时具有滚动条出现的最小尺寸,以使内容不会溢出该ContentControl区域,所以这里是一个快速介绍:
主窗口以这种方式构造:
ContentControl的模板:
实际问题是ContentControl在您调整窗口大小时会增长,但不会随着窗口大小调整而缩小.
主视图XAML(为清晰起见截断):
<ScrollViewer Grid.Row="5" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<ContentControl Grid.Row="5" Background="Transparent" Focusable="False" Margin="0,5,0,0"
Content="{Binding CurrentSection}" ContentTemplateSelector="{StaticResource templateSelector}/>
</ScrollViewer>
Run Code Online (Sandbox Code Playgroud)
Tempate XAML(为清晰起见截断):
<Grid>
...
<ItemsControl Grid.Row="4" ItemsSource="{Binding Data.QualifyingDistributionsDividends}" x:Name="QualifyingItemsControl">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="DTLayoutGrid">
...
<Grid Grid.Row="1" x:Name="DataLayout" Width="{Binding ElementName=DTLayoutGrid, Path=ActualWidth}" HorizontalAlignment="Stretch">
...
<DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="8" HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Payments}" Style="{StaticResource DataGridStyle}" CellStyle="{StaticResource DataGridNormalCellStyle}">
</DataGrid>
</Grid>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
Run Code Online (Sandbox Code Playgroud)
那会发生什么?Datagrid假设整个宽度DataTemplate(以及其设置为DataTemplates大小的底层控件,然后*列假定所有空的空间.当您尝试调整保存此代码的整个窗口时,它将正确生长,扩展*列但似乎缩小没有"注册",它保持你扩展它的大小,在其上应用滚动条并忘记它.
我已经试过到目前为止是设置宽度ItemsControl,其潜在的父母喜欢网等,还设置大小 …
我有以下内容ControlTemplate:
<ContentControl Content="{Binding ContentViewModel}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type viewModel:FilledContentViewModel}">
<usercontrols:FilledMainWindow x:Name="MainContent" />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:EmptyContentViewModel}">
<!-- todo: Something like a StartPage here -->
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
Run Code Online (Sandbox Code Playgroud)
这非常有效,直到视图模型尝试将ContentViewModel属性从 1更改FilledContentViewModel为新的FilledContentViewModel,然后 的内容ContentControl不会刷新。如果从EmptyContentViewModel到FilledContentViewModel或相反的方式切换,它就会起作用。
当然,仅更新现有的所有内容FilledContentViewModel也是一种解决方案。但我认为它可能会很快变得混乱,而只需使用ViewModel正确的上下文创建一个新的并切换它会更优雅。
有谁知道有什么方法可以让内容刷新DataTemplate吗?
contentcontrol ×10
wpf ×9
datatemplate ×4
c# ×2
xaml ×2
binding ×1
contextmenu ×1
controls ×1
datatrigger ×1
events ×1
scrollviewer ×1
width ×1