how can I bind properties of an object that is already a property of an already bound object?

I'm having a problem trying to bind the properties of an object, that is already a property of another object. When I bind the properties of the upper object, everything goes ok, but when I try to bind the properties of one property, it doesn't display anything.

Here is my code: xaml

    <Window x:Class="WpfTutorialSamples.ListView_control.ListViewColumnSortingSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ListViewColumnSortingSample" Height="200" Width="550">
    <Grid Margin="10">
        <ListView Name="lvUsers">
            <ListView.Resources>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                </Style>
            </ListView.Resources>
            <ListView.View>
                <GridView>
                    <GridViewColumn Width="120" DisplayMemberBinding="{Binding Transponder}">
                        <GridViewColumn.Header>
                            <GridViewColumnHeader Tag="Transponder" Click="lvUsersColumnHeader_Click">Transponder</GridViewColumnHeader>
                        </GridViewColumn.Header>
                    </GridViewColumn>
                    <GridViewColumn Width="80" DisplayMemberBinding="{Binding Tipo}">
                        <GridViewColumn.Header>
                            <GridViewColumnHeader Tag="Tipo" Click="lvUsersColumnHeader_Click">Tipo</GridViewColumnHeader>
                        </GridViewColumn.Header>
                    </GridViewColumn>
                    <GridViewColumn Width="110" DisplayMemberBinding="{Binding Destruida}">
                        <GridViewColumn.Header>
                            <GridViewColumnHeader Tag="Destruida" Click="lvUsersColumnHeader_Click">Destruida</GridViewColumnHeader>
                        </GridViewColumn.Header>
                    </GridViewColumn>
                    <GridViewColumn Width="80" >
                        <GridViewColumn.Header>
                            <GridViewColumnHeader Tag="Combustible">Combustible</GridViewColumnHeader>
                        </GridViewColumn.Header>
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>

                                <ComboBox  SelectionChanged="ComboBox_StopChanges" DataContext="{Binding Combustible}">
                                    <ComboBox.Resources>
                                        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}">White</SolidColorBrush>
                                    </ComboBox.Resources>

                                    <ComboBox.Items>
                                        <StackPanel Orientation="Horizontal">
                                            <StackPanel>
                                                <StackPanel Name="stckContentLeft">
                                                    <Label BorderBrush="White" BorderThickness="1" Content="Loaded :" FontSize="12" FontWeight="SemiBold" Foreground="Black" Height="25" HorizontalAlignment="Left" Margin="2,2,0,0" VerticalAlignment="Top"  Width="95"/>
                                                    <Label BorderBrush="White" BorderThickness="1" Content="Used :" FontSize="12" FontWeight="SemiBold" Foreground="Black" Height="25" HorizontalAlignment="Left" Margin="2,2,0,0" VerticalAlignment="Top"  Width="95"/>
                                                </StackPanel>
                                            </StackPanel>
                                            <StackPanel>
                                                <StackPanel Name="stckContentRigth">
                                                    <TextBox Name="textBoxLoaded" Height="25" Width="115" MaxLength="3" Margin="2,2,0,0" BorderBrush="Black" BorderThickness="1" FontSize="12" FontWeight="SemiBold" HorizontalAlignment="Left" Text="{Binding Cargado}" VerticalAlignment="Top" />
                                                    <TextBox Name="textBoxUsed" Height="25" Width="115" MaxLength="3" Margin="2,2,0,0" BorderBrush="Black" BorderThickness="1" FontSize="12" FontWeight="SemiBold" HorizontalAlignment="Left" Text="{Binding Usado}" VerticalAlignment="Top" />
                                                </StackPanel>
                                            </StackPanel>
                                        </StackPanel>
                                    </ComboBox.Items>
                                </ComboBox>

                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

And the c# code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media;

namespace WpfTutorialSamples.ListView_control
{
    public partial class ListViewColumnSortingSample : Window
    {
        private GridViewColumnHeader listViewSortCol = null;
        private SortAdorner listViewSortAdorner = null;

        public ListViewColumnSortingSample()
        {
            InitializeComponent();
            List<User> items = new List<User>();
            items.Add(new User() { Transponder = "M001", Tipo = "UH60", Destruida = Estado_Aeronave.Destruida, combustible = new Combustible() {Cargado = 4000, Usado = 3000} });
            items.Add(new User() { Transponder = "M002", Tipo = "UH70", Destruida = Estado_Aeronave.Funcional, combustible = new Combustible() { Cargado = 3000, Usado = 2000 } });
            items.Add(new User() { Transponder = "M003", Tipo = "UH80", Destruida = Estado_Aeronave.Funcional, combustible = new Combustible() { Cargado = 2000, Usado = 1000 } });
            items.Add(new User() { Transponder = "M004", Tipo = "UH90", Destruida = Estado_Aeronave.Destruida, combustible = new Combustible() { Cargado = 1000, Usado = 500 } });
            lvUsers.ItemsSource = items;
        }

        private void lvUsersColumnHeader_Click(object sender, RoutedEventArgs e)
        {
            GridViewColumnHeader column = (sender as GridViewColumnHeader);
            string sortBy = column.Tag.ToString();
            if (listViewSortCol != null)
            {
                AdornerLayer.GetAdornerLayer(listViewSortCol).Remove(listViewSortAdorner);
                lvUsers.Items.SortDescriptions.Clear();
            }

            ListSortDirection newDir = ListSortDirection.Ascending;
            if (listViewSortCol == column && listViewSortAdorner.Direction == newDir)
                newDir = ListSortDirection.Descending;

            listViewSortCol = column;
            listViewSortAdorner = new SortAdorner(listViewSortCol, newDir);
            AdornerLayer.GetAdornerLayer(listViewSortCol).Add(listViewSortAdorner);
            lvUsers.Items.SortDescriptions.Add(new SortDescription(sortBy, newDir));
        }



        private void ComboBox_StopChanges(object sender, SelectionChangedEventArgs e)
        {
            ComboBox snd = sender as ComboBox;
            snd.SelectedIndex = -1;
        }
    }

    public enum Estado_Aeronave { Destruida, Funcional };

    public class Combustible
    {
        public int Cargado { get; set; }
        public int Usado { get; set; }
    }

    public class User
    {
        public string Transponder { get; set; }

        public string Tipo { get; set; }

        public Estado_Aeronave Destruida { get; set; }

        public Combustible combustible { get; set; }
    }

    public class SortAdorner : Adorner
    {
        private static Geometry ascGeometry =
                Geometry.Parse("M 0 4 L 3.5 0 L 7 4 Z");

        private static Geometry descGeometry =
                Geometry.Parse("M 0 0 L 3.5 4 L 7 0 Z");

        public ListSortDirection Direction { get; private set; }

        public SortAdorner(UIElement element, ListSortDirection dir)
            : base(element)
        {
            this.Direction = dir;
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);

            if (AdornedElement.RenderSize.Width < 20)
                return;

            TranslateTransform transform = new TranslateTransform
                    (
                            AdornedElement.RenderSize.Width - 15,
                            (AdornedElement.RenderSize.Height - 5) / 2
                    );
            drawingContext.PushTransform(transform);

            Geometry geometry = ascGeometry;
            if (this.Direction == ListSortDirection.Descending)
                geometry = descGeometry;
            drawingContext.DrawGeometry(Brushes.Black, null, geometry);

            drawingContext.Pop();
        }
    }
}

If you could help I would forever be thankful to you.

Have a nice day.

Upvotes: 0

Views: 131

Answers (2)

shofstetter
shofstetter

Reputation: 254

Set the DataContext to the actual attribute name:

<ComboBox  SelectionChanged="ComboBox_StopChanges"  DataContext="{Binding combustible}">

And the TextBox Bindings to the according members:

<TextBox Name="textBoxLoaded" Height="25" Width="115" MaxLength="3" Margin="2,2,0,0" BorderBrush="Black" BorderThickness="1" FontSize="12" FontWeight="SemiBold" HorizontalAlignment="Left" Text="{Binding Path=Cargado}" VerticalAlignment="Top" />

<TextBox Name="textBoxUsed" Height="25" Width="115" MaxLength="3" Margin="2,2,0,0" BorderBrush="Black" BorderThickness="1" FontSize="12" FontWeight="SemiBold" HorizontalAlignment="Left" Text="{Binding Path=Usado}" VerticalAlignment="Top" />

Upvotes: 1

Yacoub Massad
Yacoub Massad

Reputation: 27871

Add the following to the User class:

    public Combustible[] CombustibleArray
    {
        get { return new[] {combustible}; }
    }

Then instead of binding the ComboBox to combustible, bind it to CombustibleArray, like this:

<ComboBox  SelectionChanged="ComboBox_StopChanges" DataContext="{Binding CombustibleArray}">

The reason your code is not working is that ComboBox data context is expecting some kind of array. It will use the first item in the array for the first item in the ComboBox. And this is exactly what my suggested modifications will do.

Upvotes: 0

Related Questions