WhileTrueSleep
WhileTrueSleep

Reputation: 1534

Access datacontext inside a Datagrid

I got xaml code like this:

<UserControl x:Class="WindowsFormsApplication4.gg"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             xmlns:local="clr-namespace:WindowsFormsApplication4"
             x:Name="myUserControl"
             d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel>
        <TextBox Text="{Binding ElementName=myUserControl, Path=DataContext.IsActive}"></TextBox>
        <Grid>
            <DataGrid x:Name="dataGrid1" AutoGenerateColumns="false" ItemsSource="{Binding MyClass}" CanUserAddRows="False" Margin="0,0,0,-119">
                <DataGrid.Columns>

                    <!-- Caption -->
                    <DataGridTemplateColumn Header="X">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Text="{Binding Path=stringPro}" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>

                    <!-- Caption -->
                    <DataGridTemplateColumn Header="Y">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Text="{Binding ElementName=myUserControl, Path=DataContext.IsActive}" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </StackPanel>
</UserControl>

Code Behind only set data context:

this.DataContext = new SomeViewModel();

SomeClass.cs :

namespace WindowsFormsApplication4
{
    public class SomeClass
    {
        public SomeClass()
        {
            this.MyProperty = 2;
            this.stringPro = "abcsdfg";
        }

        public int MyProperty { get; set; }

        public string stringPro { get; set; }
    }
}

SomeViewModel.cs:

namespace WindowsFormsApplication4
{
    using System.Collections.Generic;

    public class SomeViewModel
    {
        public SomeViewModel()
        {
            this.IsActive = false;
            this.MyClass = new List<SomeClass>();
            this.MyClass.Add(new SomeClass());
            this.MyClass.Add(new SomeClass());
        }

        public bool IsActive { get; set; }

        public List<SomeClass> MyClass { get; set; }
    }
}

I tried to use ElementName which is working outside the ** DataGrid ** but not inside

Text="{Binding ElementName=myUserControl, Path=DataContext.IsActive}"

Upvotes: 1

Views: 1901

Answers (1)

Omri Btian
Omri Btian

Reputation: 6547

You can do that by using RelativeSource

<TextBox VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.IsActive}"/>

Tested example:

                <DataGrid x:Name="dataGrid1" AutoGenerateColumns="false" ItemsSource="{Binding MyClass}" CanUserAddRows="False" Margin="0,0,0,-119">
                <DataGrid.Columns>

                    <!-- Caption -->
                    <DataGridTemplateColumn Header="X">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Text="{Binding Path=stringPro}" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>

                    <!-- Caption -->
                    <DataGridTemplateColumn Header="Y">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.IsActive}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>

            <CheckBox IsChecked="{Binding IsActive}"/>

Changed IsActive value in Ctor

public class SomeViewModel
{
    public SomeViewModel()
    {
        this.IsActive = false;
        this.MyClass = new List<SomeClass>();
        this.MyClass.Add(new SomeClass());
        this.MyClass.Add(new SomeClass());

        // Test it
        IsActive = true;
    }

    public bool IsActive { get; set; }

    public List<SomeClass> MyClass { get; set; }
}

Upvotes: 3

Related Questions