WPF 与 Silverlight - 资源中的数据绑定

Posted

技术标签:

【中文标题】WPF 与 Silverlight - 资源中的数据绑定【英文标题】:WPF vs. Silverlight - DataBinding in resources 【发布时间】: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 尝试执行的操作... 【参考方案1】:

FrameworkElement 派生的类型可能存在问题: 来自msdn page about suitable objects in ResourceDictionaries

[...] 需要共享 [...] 从 UIElement 类型派生的任何对象本质上不是 可共享 [...]

改为从DependencyObject 派生:

public class TestWrapper : DependencyObject 

【讨论】:

以上是关于WPF 与 Silverlight - 资源中的数据绑定的主要内容,如果未能解决你的问题,请参考以下文章

WPF和Silverlight的关系

WPF和Silverlight区别

WPF/Silverlight的问题:在后台代码动态生成的控件,怎么设置动态样式 Style="DynamicResource sbStyle

如何使用WPF或Silverlight制作游戏?

Windows 8 运行时(WinRT/Windows 应用商店应用程序/Windows 10 通用应用程序)与 Silverlight 和 WPF 相比如何? [关闭]

将 WPF XAML 代码移植到 Silverlight XAML 代码