经过一段时间的silverlight-development,我目前正在做一些WPF工作......
我经常使用这个技巧在我的一些 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>
.cs 文件:
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; }
}
}
至少在我的电脑上,较低的文本 block 保持在 fallbackvalue
更新#2:
我尝试了 Matrin 发布的建议(从 DependencyObject 派生,创建自己的 DependencyProperty 等) - 它也不起作用。
然而,这一次错误消息是不同的:
“System.Windows.Data 错误:2:找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement。BindingExpression:(无路径);DataItem=null;目标元素是“TestWrapper”(HashCode=28415924);目标属性是“TheData”(键入“对象”)”
不过,我也有一些解决方法的建议:
1.) - 使用 MultiBinding --> 与 Silverlight 不兼容,在某些情况下还不够。
2.) - 使用另一个包装对象,在代码隐藏中手动设置 DataContext,像这样 --> 与 Silverlight 完全兼容(除此之外,您不能直接使用 Framework-Element - 您必须使一个从它派生的空类)
xml:
<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;
}
最佳答案
您的类型从 FrameworkElement
派生可能有问题:
来自 msdn page about suitable objects in ResourceDictionaries
[...] Being shareable is required [...] Any object that is derived from the UIElement type is inherently not shareable [...]
来自
DependencyObject
反而:public class TestWrapper : DependencyObject {}
关于WPF 与 Silverlight - 资源中的数据绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23701397/