我在 WPF 应用程序中使用 DataContextProxy 时遇到问题。当我将 DataContextProxy 放在网格的资源部分时,它永远不会加载。如果我将 DataContextProxy 移出资源部分,则一切正常。

我已经对此进行了一段时间的调查,并尝试了多种方法来调试应用程序。

  • 我在我尝试使用的控件上放置了一个 DebugConverter
    代理与。调试转换器永远不会被调用。
  • 我已经使用 WPFSnoop 来查看是否有任何绑定(bind)错误。我得到
    以下 DataContextProxy 上的绑定(bind)错误,

    System.Windows.Data 错误:3:找不到提供 DataContext 的元素。
    BindingExpression:(无路径);数据项=空;目标元素是“代理”
    (姓名='');目标属性是“DataContext”(类型“Object”)
  • 我在 DataContextProxy 的加载事件上放置了一个断点。
    加载的事件从未被调用,我在
    从未调用过的 DataContextChanged 事件。

  • 下面是一些示例代码来演示这一点。显然我知道我真的不需要在 TextBox 上使用 DataContextProxy。
    <Window x:Class="WpfDataContextProxyBug.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfDataContextProxyBug"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <local:DebugConverter x:Key="DebugConverter"/>
        </Window.Resources>
        <Grid>
            <Grid.Resources>
                <local:Proxy x:Key="Proxy" DataContext="{Binding}" />
            </Grid.Resources>
    
        <TextBox DataContext="{Binding Path=Name, Source={StaticResource Proxy}, Converter={StaticResource DebugConverter}}"/>
        </Grid>
    </Window>
    

    DataContextProxy 类
    public class Proxy : FrameworkElement
    {
        public Proxy()
        {
            Loaded += DataContextProxy_Loaded;
            DataContextChanged += Proxy_DataContextChanged;
        }
    
        void Proxy_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
    
        }
    
        void DataContextProxy_Loaded(object sender, RoutedEventArgs e)
        {
    
        }
    
    }
    

    最佳答案

    当我尝试在 WPF 中使用 DataContextProxy 时,我也遇到了这个问题。我想出了一个受它启发的解决方案,它似乎可以很好地处理这项工作。一探究竟:

    public class DataContextProxyBehavior : Behavior<FrameworkElement>
    {
        public Object DataSource
        {
            get { return (Object)GetValue(DataSourceProperty); }
            set { SetValue(DataSourceProperty, value); }
        }
        public static readonly DependencyProperty DataSourceProperty =
            DependencyProperty.Register("DataSource", typeof(Object), typeof(DataContextProxy), null);
    
        protected override void OnAttached()
        {
            base.OnAttached();
    
            // Binds the target datacontext to the proxy,
            // so whenever it changes the proxy will be updated
            var binding = new Binding();
            binding.Source = this.AssociatedObject;
            binding.Path = new PropertyPath("DataContext");
            binding.Mode = BindingMode.OneWay;
            BindingOperations.SetBinding(this, DataContextProxyBehavior.DataSourceProperty, binding);
    
            // Add the proxy to the resource collection of the target
            // so it will be available to nested controls
            this.AssociatedObject.Resources.Add(
                "DataContextProxy",
                this
            );
        }
        protected override void OnDetaching()
        {
            base.OnDetaching();
    
            // Removes the proxy from the Resources
            this.AssociatedObject.Resources.Remove(
                "DataContextProxy"
            );
        }
    }
    

    您只需要将其附加到父元素。子元素中的静态资源引用将保持不变。我已经发布了一个使用示例 here

    关于c# - 资源部分中的 WPF DataContextProxy,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10446689/

    10-13 04:57