【问题标题】:How to Pass a Parameter to a DataContext?如何将参数传递给 DataContext?
【发布时间】:2014-03-25 20:17:59
【问题描述】:

是否可以通过 XAML 将一些数据传递给绑定源/数据上下文?

在我的特定情况下,我希望为绑定源提供对创建它的窗口的引用。

例如:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:MyNamespace"
    x:Name="MyWindow">

    <Window.Resources>
        <local:MarginDataContext x:Key="MyDC"/>
    </Window.Resources>

    <!-- I want to pass in "MyWindow" to "MyDC" here... -->
    <Grid Margin="{Binding Source={StaticResource MyDC}, Path=My_Margin}" /> 
</Window>

注意:MarginDataContext 是我自己创造的,所以如果这涉及到添加构造函数参数或其他东西,那会很好用!

更新:我想要一个符合我项目特定要求的解决方案:

  • 不使用 x:Reference 扩展。
  • 使用尽可能少的代码(我希望能够在 XAML 中完成大部分工作)。

谢谢!

【问题讨论】:

    标签: c# wpf datacontext staticresource


    【解决方案1】:

    您可以在 XAML 中访问 MarginDataContext 的任何属性。因此,假设您创建了一个 WindowInstance 属性,然后您可以使用 x:Reference 在构建 MarginDataContext 时简单地分配它:

    <local:MarginDataContext x:Key="MyDC" WindowInstance="{x:Reference MyWindow}"/>
    

    【讨论】:

    • 实际上...这对我来说并不完全有效。在我的情况下,我不能使用 x:Reference 扩展:(关于如何在不使用 x:Reference 的情况下执行此操作的任何想法?
    • 我使用的平台不支持 x:Reference 扩展。您的解决方案完全可以运行标准 WPF,但不幸的是,在我的特殊情况下,我无法使用该扩展。
    • 我看到 x:Reference 是 XAML 2009 的一部分,尽管 XAML 2006 的命名空间确实接受了它。
    【解决方案2】:

    我可以想到两种方法来做到这一点,1) 使用 MarginDataContext 构造函数的参数,2) 在后面的代码中使用 DataContextChanged。

    方法一:参数化 MarginDataContext 有关详细信息,请参阅 MSDN 上的 x:Arguments Directivex:Reference

    public class MarginDataContext
    {
        public WindowInstance { get; set; }
        ...
    }
    
    <!-- xaml -->
    <Window.Resources>
        <local:MarginDataContext
            x:Key="MyDC"
            WindowInstance="{x:Reference MyWindow}" />
        <!-- or possibly (not sure about this) -->
        <local:MarginDataContext
            x:Key="MyDC"
            WindowInstance="{Binding ElementName=MyWindow}" />
        <!-- or even (again, not sure about this) -->
        <local:MarginDataContext
            x:Key="MyDC"
            WindowInstance="{Binding RelativeSource={RelativeSource Self}}" />
    </Window.Resources>
    

    方法2:使用代码隐藏。请参阅DataContextChanged 了解更多信息。

    public class MyWindow : Window
    {
        ...
        public MyWindow()
        {
            // Attach event handler
            this.DataContextChanged += HandleDataContextChanged;
    
            // You may have to directly call the Handler as sometimes
            // DataContextChanged isn't raised on new windows, but only
            // when the DataContext actually changes.
        }
    
        void HandleDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            var dc = DataContext as MarginDataContext;
            if (dc != null)
            {
                // Assuming there is a 'MyWindow' property on MarginDataContext
                dc.MyWindow = this;
            }
        }
    }
    

    【讨论】:

    • 谢谢瑞恩! BlueM 的回答非常适合我的需求,所以我实际上并没有尝试这些东西。可能会在某个时候回到它,并将结果发布在这里。再次感谢!
    • 啊,我看到 BlueM 的答案等同于 #1,只是他的语法正确。 :)
    • 这个我没试过,但是我想到了另一种不使用x:Reference的可能性。请尝试 #1 中的 {Binding} 看看它是否有效。
    猜你喜欢
    • 2019-05-08
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    • 2012-12-21
    • 2012-01-07
    • 2014-05-03
    相关资源
    最近更新 更多