Welcome to the Xceed Community | Help
Community Search  
More Search Options

Access to bound entity from a converter in a Two-Way binding scenario

Sort Posts: Previous Next
  •  07-11-2011, 5:56 PM Post no. 30702

    Access to bound entity from a converter in a Two-Way binding scenario

    I have a grid bound to a collection of users, each row is bound to a user.

    class User { int Level {get;set;}}

    How to implement two-way binding of a column HighLow:bool to a property Level:int on an entity User when to implement a conversion, converter needs to know the entity to which current row is bound (conversion logic depends on some other properties of the entity).

    I have found partial solution if one needs a one-way binding (readonly). In this case entity can be bound to Path property and converter gets the entity in its value parameter. Column name can be passed through converter parameter or through constructor. But it doesn't work in two-way scenario because in this example it isn't possible to convert back bool column value to User (passed through Path) property.

    I am really stuck with this problem. Does somebody know a solution?

    Thanks.

  •  07-12-2011, 4:30 PM Post no. 30710 in reply to 30702

    Re: Access to bound entity from a converter in a Two-Way binding scenario

    Hi Alexander, 

    Can you send us a sample with more details on what you are trying to achieve so that we investigate this in more detail?

    You can send it to support@xceed.com. Please include a reference to this forum thread in your email.  


    Best Regards,

    Michel Dahdah
    Technical Support
    Xceed Software inc.
  •  07-12-2011, 5:53 PM Post no. 30713 in reply to 30710

    Re: Access to bound entity from a converter in a Two-Way binding scenario

    1) Let say you want to bind the list of commodities to a Xceed grid. Whether to display property Value in decimal or percentage format depends on DisplayPercents property.
    public class Commodity
    {
        public string Name { get; set; }
        public bool DisplayPercents { get; set; }
        public double Value { get; set; }
    }
    2) Converters looks like this:
        public class CommodityConverter : IValueConverter
        {
            // this method returns entity bounded to the current row
            private Commodity AquireSomewhereBoundCommodity(object valueObj, object parameter)
            {
                // TODO: how to get bounded parnet?
                return valueObj as Commodity;
            }
           
            public object Convert(object valueObj, Type targetType, object parameter, CultureInfo culture)
            {
                var commodity = AquireSomewhereBoundCommodity(valueObj,parameter);
                if (commodity != null)
                {
                    // convert from decimal to percents
                    return commodity.DisplayPercents ? commodity.Value*100 : commodity.Value;
                }
                return valueObj;
            }

            public object ConvertBack(object valueObj, Type targetType, object parameter, CultureInfo culture)
            {
                var commodity = AquireSomewhereBoundCommodity(valueObj, parameter);
                if (commodity != null)
                {
                    // convert from percents back to decimals
                    return commodity.DisplayPercents ? commodity.Value / 100 : commodity.Value;
                }
                return valueObj;
            }
        }
    3) Here is a UI part. I tried also combination FieldName=Value and Path=Value.
        <xcdg:DataGridControl AutoCreateColumns="False" ItemsSource="{Binding Commodities}">
            <xcdg:DataGridControl.Columns>
                <xcdg:Column FieldName="Name" AllowSort="False" AllowGroup="False" />
                <!--or try FieldName=Value and Path=Value-->
                <xcdg:Column FieldName="." AllowSort="False" AllowGroup="False">
                    <xcdg:Column.DisplayMemberBindingInfo>
                        <xcdg:DataGridBindingInfo Path="." Converter="{StaticResource conv1}"/>
                    </xcdg:Column.DisplayMemberBindingInfo>
                </xcdg:Column>
            </xcdg:DataGridControl.Columns>
        </xcdg:DataGridControl>
    4) Here is a codebehind
        public partial class TwoWayBindingUsingParentEntityWindow : Window
        {
            readonly ObservableCollection<Commodity>  commodities=new ObservableCollection<Commodity>();

            public TwoWayBindingUsingParentEntityWindow()
            {
                InitializeComponent();

                commodities.Add(new Commodity {Name="Wood", DisplayPercents = false, Value=12});
                commodities.Add(new Commodity {Name="Silver", DisplayPercents = true, Value=0.115});
                DataContext = this;
            }

            public ObservableCollection<Commodity>  Commodities
            {
                get { return commodities; }
            }
        }
  •  07-13-2011, 11:23 AM Post no. 30717 in reply to 30713

    Re: Access to bound entity from a converter in a Two-Way binding scenario

    Hi Alexander, 

    You can achieve this by changing the cellcontenttemplate of the "Value" column to a Textblock with a MultiBinding that uses an IMultiBindingConverter. That way you can bind to your DisplayPercentage field or any other field in your entity.

    It would something like this:

    <xcdg:DataGridControl x:Name="myGrid" AutoCreateColumns="True" UpdateSourceTrigger="CellContentChanged" >

    <xcdg:DataGridControl.Columns>

    <xcdg:Column FieldName="Name" AllowSort="False" AllowGroup="False" />

    <xcdg:Column FieldName="Value" AllowSort="False" AllowGroup="False">

    <xcdg:Column.CellContentTemplate>

    <DataTemplate>

    <TextBlock>

    <TextBlock.Text>

    <MultiBinding Converter="{StaticResource conv1}">

    <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type xcdg:DataCell},AncestorLevel=1}" Path="ParentColumn.FieldName"/>

    <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type xcdg:DataRow},AncestorLevel=1}" Path="DataContext.DisplayPercents"/>

    <Binding RelativeSource="{RelativeSource FindAncestor,

    AncestorType={x:Type xcdg:DataRow},AncestorLevel=1}" Path="DataContext.Value"/>

    </MultiBinding>

    </TextBlock.Text>

    </TextBlock>

    </DataTemplate>

    </xcdg:Column.CellContentTemplate>

    </xcdg:Column>

    </xcdg:DataGridControl.Columns>

    </xcdg:DataGridControl>

    public class CommodityConverter : IMultiValueConverter

    {

    public object Convert( object[] values, Type targetType, object parameter, CultureInfo culture )

    {

    String fieldName = values[ 0 ] as string;

    bool? DisplayPercents = values[ 1 ] as bool?;

    double? Value = values[ 2 ] as double?;

    if( DisplayPercents != null && Value != null )

    {

    if( fieldName.Equals( "Value" ) )

    {

    return (DisplayPercents.Value ? Value / 100 : Value).ToString();

    }

    }

    return Value.ToString();

    }

    You can find a related post in the following blog:

    Best Regards,

    Michel Dahdah
    Technical Support
    Xceed Software inc.
View as RSS news feed in XML
Contact | Site Map | Reviews | Legal Terms of Use | Trademarks | Privacy Statement Copyright 2011 Xceed Software Inc.