我经常使用这个技巧让我的一些ValueConverters生活更轻松:
public class MyCovnerterWithDataContext : FrameworkElement, IValueConverter
{
private MyDataContextType Data
{
get { return this.DataContext as MyDataContextType; }
}
....
现在我可以在Converter-Method中访问我的DataContext,这在很多情况下都很方便。
我在WPF中尝试了相同的技巧并发现,不幸的是,这根本不起作用。调试输出中存在以下错误:
“找不到提供DataContext的元素”
我认为资源不是WPF中可视化树的一部分,而是在Silverlight中。
那么 - 在WPF中我的小技巧也是可能的吗? 我的小伎俩被认为是一个肮脏的黑客?
您有什么意见和建议?
此致 约翰内斯
更新: 根据要求提供更多信息 - 实际上是一个最小的例子:
XAML:
<Window x:Class="WpfDataContextInResources.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfDataContextInResources"
x:Name="window"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:TestWrapper x:Key="TestObj" />
</Window.Resources>
<StackPanel>
<TextBlock Text="{Binding Text}" />
<TextBlock Text="{Binding DataContext.Text, Source={StaticResource TestObj}, FallbackValue='FALLBACK'}" />
</StackPanel>
</Window>
<。p。文件:
namespace WpfDataContextInResources
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new DataClass()
{
Text = "Hello",
};
}
}
public class TestWrapper : FrameworkElement {}
public class DataClass
{
public string Text { get; set; }
}
}
至少在我的电脑上,较低的文本块保留在后备值
更新#2:
我尝试了Matrin发布的建议(从DependencyObject派生,创建自己的DependencyProperty等) - 它也不起作用。 但是,这次错误消息是另一个错误消息:
“System.Windows.Data错误:2:无法找到目标元素的管理FrameworkElement或FrameworkContentElement。BindingExpression :(无路径); DataItem = null;目标元素是'TestWrapper'(HashCode = 28415924);目标属性是'数据'(类型'对象')“
我也有一些解决方法的建议:
1。) - 使用MultiBinding - &gt;与Silverlight不兼容,在某些情况下还不够。
2。) - 使用另一个包装对象,在代码隐藏中手动设置DataContext,像这样 - &gt;与Silverlight完全兼容(除了你不能直接使用Framework-Element这一事实 - 你必须创建一个从它派生的空类)
XAML:
<Window.Resources>
<FrameworkElement x:Key="DataContextWrapper" />
<local:TestWrapper x:Key="TestObj" DataContext="{Binding DataContext, Source={StaticResource DataContextWrapper}}" />
...
代码背后的代码:
//of course register this handler!
void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var dcw = this.Resources["DataContextWrapper"] as FrameworkElement;
dcw.DataContext = this.DataContext;
}
答案 0 :(得分:0)
您的类型可能来自FrameworkElement
:
来自msdn page about suitable objects in ResourceDictionaries
[...]需要可分享[...] 从UIElement类型派生的任何对象本身都不是 可分享的[...]
从DependencyObject
代替:
public class TestWrapper : DependencyObject {}