I have a UserControl that has a XamNumericEditor as a part of the Tree.
I am trying to set its binding value at runtime and add it dynamically to the children of a control.
This pattern works with TextBox, Button, ComboBox and some other controls. But I can't seem to get it to work with an Infragistic control. Nothing binds to it...but on all the other controls it works.
Please help!
Here is my simplified UserControl XAML
<UserControl x:Class="SilverlightApplication1.XText" 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" mc:Ignorable="d" xmlns:ig="http://schemas.infragistics.com/xaml" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> <ig:XamNumericEditor Name="MyNumericEditor"/> </Grid></UserControl>Here is my code behindpublic partial class XText : UserControl { public XText() { InitializeComponent(); MyNumericEditor.SetBinding(XamNumericEditor.ValueProperty, new Binding() { Source = this, Path = new PropertyPath("MyText"), Mode = BindingMode.TwoWay }); } public double MyText { get { return (double)GetValue(MyTextProperty); } set { SetValue(MyTextProperty, value); } } public static readonly DependencyProperty MyTextProperty = DependencyProperty.Register( "MyText", typeof(double), typeof(XText), new PropertyMetadata(null)); }And when I want to use it string s = @"<uc:XText MyText=""{Binding Path=" + path + @", Mode=TwoWay}""/>";
public partial class XText : UserControl { public XText() { InitializeComponent(); MyNumericEditor.SetBinding(XamNumericEditor.ValueProperty, new Binding() { Source = this, Path = new PropertyPath("MyText"), Mode = BindingMode.TwoWay }); } public double MyText { get { return (double)GetValue(MyTextProperty); } set { SetValue(MyTextProperty, value); } } public static readonly DependencyProperty MyTextProperty = DependencyProperty.Register( "MyText", typeof(double), typeof(XText), new PropertyMetadata(null));
string s = @"<uc:XText MyText=""{Binding Path=" + path + @", Mode=TwoWay}""/>";
How about this instead of setting the binding in LayoutUpdated I could still do it on Loaded and then when the XText is unloaded do this:
private void XText_Unloaded(object sender, RoutedEventArgs e){
this.MyNumericEditor.ClearValue(XamNumericEditor.ValueProperty);}This seems to work too...
Hi,
It still seems to be some timing issue. The Loaded event of your custom user control might not be the best place to create this binding. I modified your sample and placed the Binding creation in LayoutUpdated event, and now it's working fine for me.
However, a better approach here would be to make your XText class inherit from Control instead of UserControl and move this logic in OnApplyTemplate.
Hope that helps,
Georgi,
Your example does work better but if you start clicking around on the grid between different cells I still get an unhandled exception "System.InvalidOperationException: operation is not valid due to the current state of the object"
I'm not sure if this is a Grid Problem or a UserControl issue.
System.Windows.Data.BindingExpression.UpdateSource() at Infragistics.Controls.Grids.CellControl.EvaluateEditingBindings() at Infragistics.Controls.Grids.Cell.ExitEditMode(Object newValue, Boolean editingCanceled) at Infragistics.Controls.Grids.XamGrid.ExitEditModeInternal(Boolean cancel) at Infragistics.Controls.Grids.XamGrid.SetActiveCell(CellBase cell, CellAlignment alignment, InvokeAction action, Boolean allowSelection, Boolean setFocus, Boolean scrollIntoView) at Infragistics.Controls.Grids.XamGrid.SetActiveCell(CellBase cell, CellAlignment alignment, InvokeAction action, Boolean allowSelection, Boolean scrollIntoView) at Infragistics.Controls.Grids.XamGrid.SetActiveCell(CellBase cell, CellAlignment alignment, InvokeAction action, Boolean allowSelection) at Infragistics.Controls.Grids.Cell.OnCellMouseDown(MouseEventArgs e) at Infragistics.Controls.Grids.XamGrid.XamWebGrid_MouseLeftButtonDown(Object sender, MouseButtonEventArgs e) at MS.Internal.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args) at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName)
I have attached an updated example.
Please Help!
Well it will work if I don't use it for both the ItemTemplate and the EditorTemplate.
I guess I can work with that... unless there is another solution.
Hi gmcalab,
Is it necessary to use ‘XamNumericEditor’ for the ‘ItemTemplate’ ? You can use, in this case the ‘TextBlock’ and your code will look:
public MainPage()
{
InitializeComponent();
int numOfColumns = 3;
for (int i = 0; i < 10; i++)
Row r = new Row();
for (int j = 0; j < numOfColumns; j++)
Cell c = new Cell();
c.Key = keys[j];
if( i > 0 )
c.Value = String.Format("{0}{1}", i, j);
else
c.Value = String.Format("{0}", j);
r.Cells.Add(c);
}
r.RowIndex = i;
Rows.Add(r);
for (int i = 0; i < numOfColumns; i++)
UnboundColumn column = new UnboundColumn();
column.ItemTemplate =
CreateItems(String.Format("RowData.Cells[{0}].Value", i));
column.EditorTemplate =
Create(String.Format("RowData.Cells[{0}].Value", i));
column.Key = keys[i];
XamGrid.Columns.Add(column);
this.model.Rows = this.Rows;
this.XamGrid.DataContext = this.model;
public static DataTemplate CreateItems(string path)
return (DataTemplate)XamlReader.Load(
@"<DataTemplate
xmlns=""http://schemas.microsoft.com/client/2007""
xmlns:uc=""clr-namespace:TestApp;assembly=TestApp"">
<TextBlock Text=""{Binding Path=" + path + @", Mode=TwoWay}""
MinWidth=""100""/>
</DataTemplate>"
);
Will this help?