Multiple dataContext for one control - MVVM

前端 未结 3 1229
广开言路
广开言路 2020-12-10 15:32

I am not sure if my question header represent exactly my problem, I will do the best to explain:

I have a grid cell DataTemplate: (the grid belong to third party com

相关标签:
3条回答
  • 2020-12-10 16:00

    There are some binding properties you can use to specify a different Source for your binding than the default DataContext

    The most common ones are ElementName or RelativeSource, which will find another UI element in the VisualTree so you can bind to it's properties.

    For example, the following uses ElementName to tell the binding that it should use MyGridView as the binding source, and to bind to MyGridView.DataContext.OpenLinkCommand

    <Hyperlink Command="{Binding ElementName=MyGridView, 
                                 Path=DataContext.OpenLinkCommand}"> 
    

    You can also use RelativeSource in a binding to find an object further up the VisualTree of the specified object type, and use it as the binding source. This example does the same thing as the above example, except it uses RelativeSource instead of ElementName, so your GridView doesn't need to have a Name specified.

    <Hyperlink Command="{Binding 
                   RelativeSource={RelativeSource AncestorType={x:Type GridView}}, 
                   Path=DataContext.OpenLinkCommand}"> 
    

    A third option is to set the binding's Source property to a static object, like this:

    <Hyperlink Command="{Binding 
                   Source={x:Static local:MyStaticClass.OpenLinkCommand}}"> 
    

    Based on your comment here about binding to a singleton, this would probably be the best option for you.

    0 讨论(0)
  • 2020-12-10 16:10

    You will have to have an instance of the desired data context (usually in the resources of a control or window). Once you have that, you should be able to explicitly set the data context of the textblock instead of inheriting the parent data context automatically.

    For example:

    <TextBlock DataContext="{StaticResource MyDataMapLinkDataContext}" Text="{Binding Data.MapLink}" TextDecorations="underline"/>
    
    0 讨论(0)
  • 2020-12-10 16:18

    If you really do need to use another property for an extra data context then you can just use an attached property.

    XAML

        <Window.Resources>
            <Style TargetType="Button">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="Button">
                            <ContentPresenter Content="{Binding (local:ExtraDataContextProvider.ExtraDataContext), RelativeSource={RelativeSource TemplatedParent}}"/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Window.Resources>
    
        <Grid>
            <Button Margin="172,122,131,79" Foreground="Green" local:ExtraDataContextProvider.ExtraDataContext="A test">
                test
            </Button>
        </Grid>
    </Window>
    

    Code

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace WpfApplication1
    {
    
        public class ExtraDataContextProvider : DependencyObject
        {
            public static object GetExtraDataContext(DependencyObject obj)
            {
                return (object)obj.GetValue(ExtraDataContextProperty);
            }
    
            public static void SetExtraDataContext(DependencyObject obj, object value)
            {
                obj.SetValue(ExtraDataContextProperty, value);
            }
    
            public static readonly DependencyProperty ExtraDataContextProperty = DependencyProperty.RegisterAttached("ExtraDataContext", typeof(object), typeof(ExtraDataContextProvider), new PropertyMetadata(null));
        }
    
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题