【发布时间】:2014-07-05 06:25:33
【问题描述】:
经过一段时间的 silverlight 开发,我目前正在做一些 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; }
}
}
至少在我的电脑上,较低的文本块保持在后备值上
更新 #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 - 您必须创建一个从中派生的空类)
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;
}
【问题讨论】:
-
有趣。使用存根的 MyDataContextType,它可以编译并为我工作(前 Silverlight 人)。请详细了解此 IValueConverter 尝试执行的操作...
标签: wpf silverlight binding