我使用datatemplate来可视化ComboBox中的一些项目,ItemsSource绑定到ObservableCollection.为了简单起见,让我说我把人放入ObservableCollection:
public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我的DataTemplate看起来像这样:
<DataTemplate TargetType="{x:Type Person}">
<StackPanel Orientation="Horizontal">
<TextSearch.Text>
<MultiBinding StringFormat="{} {0} {1}">
<Binding Path="FirstName"/>
<Binding Path="LastName"/>
</MultiBinding>
</TextSearch.Text>
<TextBlock Text="{Binding FirstName}" Margin="2,0" />
<TextBlock Text="{Binding LastName}"/>
</StackPanel>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
现在我想在ComboBox中为全名启用自动完成功能,而不在我的person类上引入第三个属性.因此我不想在ComboBox上使用TextSearch.TextPath属性,而是想在DataTemplate中绑定每个ComboBoxItem的TextSearch.Text-Property.不幸的是,当我这样做(使用MultiBinding和StringFormat,使用Snoop测试)时,绑定值仅为我的StackPanel注册,但是使用Snoop(很棒的工具)我发现这个stackpanel就像其他一些ComboBoxItemTemplate的内容一样,它放置另一个边框等,最后一个ComboBoxItem标签围绕我的外部StackPanel.因此,TextSearch.Text设置无效,因为它必须在创建的ComboBoxItem中设置,而不是在其中的某个位置.
现在问题:如何使用XAML-Styles和-Control-Templates将我的DataTemplate中的TextSearch.Text-Property传播到周围的ComboBoxItem?该解决方案可能会修改ComboBox和ComboBoxItem的默认ControlTemplates以及我的自定义(Item-)DataTemplate,但不会使用任何Code-Behind,或者至少不会太多.也许附加的行为也可以.但我几乎肯定必须有一种方法可以让它无需工作,TemplateBinding或RelativeSource-stuff ......当然,解决方案必须使我的键盘选择和文本完成工作,s.当名单中包含汉斯约瑟夫和汉斯彼得,然后进入'汉斯'应该自动提出汉斯约瑟夫,而进入'汉斯P'足够快应该自动提出汉斯彼得.
有解决方案吗
我正在尝试构建一个ContentControl派生的控件(让我们称之为MyContentControl),它将ControlTemplate由一个DataTemplateSelector-derived类型的实例设置(让我们称之为MyTemplateSelector).
当我尝试这个:
ContentControl contentControl = new ContentControl();
contentControl.ContentTemplateSelector = new MyTemplateSelector();
contentControl.Content = "Some ContentControl Content";
MyContentControl myContentControl = new MyContentControl();
myContentControl.ContentTemplateSelector = new MyTemplateSelector();
myContentControl.Content = "Some MyControl Content";
Run Code Online (Sandbox Code Playgroud)
我希望,当我在这些控件上设置内容时,会同时调用方法MyTemplateSelector的覆盖和 .DataTemplateSelector.SelectTemplate()contentControlmyContentControl
实际上,只为contentControl调用它.我需要做什么(以及为什么!)才能使其发挥作用myContentControl?
(不确定它是否相关,但目前除了覆盖元数据信息之外MyContentControl没有做任何DependencyProperties其他事情DefaultStyleKeyProperty.
编辑(将内容从其他帖子转移到原始问题):
这是一个更详细的例子:
创建MyContentControl:
public class MyContentControl : ContentControl
{
static MyContentControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof (MyContentControl),
new FrameworkPropertyMetadata(typeof (MyContentControl)));
}
public MyContentControl() {}
} …Run Code Online (Sandbox Code Playgroud)如何选择一个不同的数据模板来匹配数据绑定源中的字段?我会有2个不同的DataTemplates
<DataTemplate x:Key="DataTemplateLabel">
<Label Width="60" Height="25" Background="Red">
<TextBlock Text="{Binding Path=Name}"/>
</Label>
</DataTemplate>
<DataTemplate x:Key="DataTemplateTxtBox">
<TextBox Width="60" Height="25" Background="Red" Text="{Binding Path=Text}"/>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
if(isText)然后使用DataTemplateTxtBox ELSE使用DataTemplateLabel)这可能吗?谢谢.
我正在尝试在RadGridView中创建一系列绑定列,我正在使用模板在两个列中创建超链接.这基本上就是我所拥有的:
<telerik:GridViewDataColumn IsReadOnly="True" UniqueName="Distributor" DataContext="{Binding Distributor}" CellTemplate="{StaticResource linkTemplate}"/>
Run Code Online (Sandbox Code Playgroud)
和,
<DataTemplate x:Key="linkTemplate">
<TextBlock>
<Hyperlink DataContext={TemplateBinding DataContext} Click="Hyperlink_Click">
<TextBlock Text="{Binding Name}" />
</Hyperlink>
</TextBlock>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
RadGridView本身绑定到一组DistributorContainer对象,这些对象具有Distributor属性等.linkTemplate直接引用Distributor对象中的属性,因此需要将超链接的datacontext设置为Distributor.
不幸的是,Hyperlink的数据上下文是DistributorContainer对象.我在绑定到分销商列表的列表上使用linkTemplate(以及Hyperlink_Click处理程序),我真的想重新使用这个模板,因为它基本上是一样的.
为什么模板不通过TemplateBinding到GridViewDataColumn将Distributor作为其DataContext?
我编写了一个片段来通过c#代码创建自己的DataTemplate.然后我将它添加到datagrid列的编辑模板中.当我调用时object templateContent = tc.CellTemplate.LoadContent ( );,应用程序崩溃,并抛出一个异常,"FrameworkElementFactory必须在此操作的密封模板中.".这是我创建datatemplate的代码.
public override DataTemplate GenerateCellTemplate ( string propertyName )
{
DataTemplate template = new DataTemplate ( );
var textBlockName = string.Format ( "{0}_TextBlock", propertyName );
FrameworkElementFactory textBoxElement = new FrameworkElementFactory ( typeof ( TextBlock ), textBlockName );
textBoxElement.SetBinding ( TextBlock.TextProperty, new Binding ( propertyName ) );
template.VisualTree = textBoxElement;
Trigger trigger = new Trigger ( );
return template;
}
Run Code Online (Sandbox Code Playgroud) wpf exception datatemplate wpfdatagrid frameworkelementfactory
我对WPF中的数据模板有一般性问题.假设我有一个名为"问题"的抽象类,以及各种子类,如"MathQuestion","GeographyQuestion"等.在某些情况下,使用"问题"数据模板将问题呈现为"问题"已经足够了,但是假设我有一个不同子类的随机问题对象列表,我想反过来显示它们.我想使用他们的特定数据模板而不是他们的通用问题数据模板将它们显示给用户,但由于我不知道在设计时,无论如何都告诉WPF,"嘿,这是一个Quesitons列表,但是使用反射来弄清楚他们的具体类型并使用那个数据模板?"
我曾想过到目前为止:我认为,除了有我的问题集,我使用反射可以创建特定类型的另一采集并以某种方式结合,为"嗒嗒",那么我会得到预期的影响,但你只能绑定到WPF中的DependencyProperties,所以我不确定我绑定到什么.我真的不喜欢这个想法,我的直觉告诉我有一个更优雅的方法来解决这个问题.
我不是在寻找具体的代码,只是一个完成我想要做的事情的一般策略.另外,如果有帮助的话,我大部分时间都在使用MVVM.
谢谢
我对TemplateBinding和TemplatedParent感到困惑.我已经通过这个链接 WPF TemplateBinding vs RelativeSource TemplatedParent
但我怀疑何时使用TemplateBinding和TemplatedParent?
提前致谢.
编辑:当使用标准.NET ResourceDictionary时也会出现此问题,并且似乎是在控件或数据模板中使用资源字典的问题.
我有一个自定义资源字典遵循共享资源实例的常见方法.
http://softnotes.wordpress.com/2011/04/05/shared-resourcedictionary-for-silverlight/ http://www.wpftutorial.net/MergedDictionaryPerformance.html
public class SharedResourceDictionary : ResourceDictionary
{
static readonly Dictionary<Uri, WeakReference<ResourceDictionary>> SharedDictionaries = new Dictionary<Uri, WeakReference<ResourceDictionary>>();
Uri _sourceUri;
public new Uri Source
{
get
{
// Behave like standard resource dictionary for IDE...
if (VisualStudio.IsInDesignMode)
return base.Source;
return this._sourceUri;
}
set
{
// Behave like standard resource dictionary for IDE...
if (VisualStudio.IsInDesignMode)
{
base.Source = value;
return;
}
this._sourceUri = value;
WeakReference<ResourceDictionary> cached;
if (SharedDictionaries.TryGetValue(value, out cached))
{
ResourceDictionary rd;
if (cached.TryGetTarget(out rd))
{
this.MergedDictionaries.Add(rd);
return; …Run Code Online (Sandbox Code Playgroud) 假设我有一个项目控件绑定到VM上的项目列表.datatemplate内部是一个文本框.如何将焦点设置为XAML或VM中的第一个文本框?
在此先感谢您的帮助!
<ItemsControl ItemsSource="{Binding UsageItems}" Grid.Row="1" Focusable="False">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Month}" Style="{StaticResource Local_MonthLabel}" />
<core:NumericTextBox Value="{Binding Actual, Mode=OneWay}" Style="{StaticResource Local_ActualUsageEntry}" Grid.Column="2"/>
<core:ValidationControl Instance="{Binding Model}" Grid.Column="4" PropertyName="{Binding MonthNumber, StringFormat=AdjustedUsage{0}}">
<core:NumericTextBox Value="{Binding Adjusted}" DefaultValueIfNull="0" Style="{StaticResource Local_AdjustUsageEntry}" x:Name="AdjustmentEntry" inventoryLocationSetup:InitialFocusBehavior.Focus="True" />
</core:ValidationControl>
<telerik:RadComboBox ItemsSource="{Binding Converter={StaticResource Converter_EnumToEnumMemberViewModel}, Mode=OneTime, Source={x:Type Enums:UsageAdjustmentTypes}}" SelectedValue="{Binding Code, Mode=TwoWay}" Grid.Column="6" Style="{StaticResource Local_CodeSelector}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
Run Code Online (Sandbox Code Playgroud)
我有一个ListBox它ItemTemplate看起来像这样:
<DataTemplate DataType="local:Column">
<utils:EditableTextBlock x:Name="editableTextBlock" Text="{Binding Name, Mode=TwoWay}"/>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
Column 是一个简单的类,看起来像这样:
public Column(string name, bool isVisibleInTable)
{
Name = name;
IsVisibleInTable = isVisibleInTable;
}
public string Name { get; set; }
public bool IsVisibleInTable { get; set; }
Run Code Online (Sandbox Code Playgroud)
该EditableTextBlock是UserControl说变成了TextBox双次点击时回百转成TextBlock失落时对焦.它还有一个被称为属性的属性IsInEditMode,默认为false.如果是,TextBox则显示.
问题:
在ItemsSouceListBox的是ObservableCollection<Column>.我有一个按钮,Column可以为集合添加新的内容.但我的问题是,我希望通过该ButtonIsInEditMode为新添加的EditableTextBlocks 变为真.但我只能在ViewModel中访问.我如何访问集合中指定的? ColumnEditableTextBlockColumnItemsSource
我能想出的唯一解决方案是从中派生一个类Column并为其添加一个属性(例如:name:IsInEditMode)(或者也许是一个包装类.这里是一个类似的答案,建议使用包装类)并绑定到该属性DataTemplate如下: …
datatemplate ×10
wpf ×10
c# ×4
data-binding ×2
mvvm ×2
binding ×1
combobox ×1
exception ×1
focus ×1
itemscontrol ×1
listbox ×1
telerik ×1
wpfdatagrid ×1
xaml ×1