Hello,
i added a simple example which should explain all.
I created a CustomButtonEditor (inherited from ValueEditor) which contains a Button Control. I created some bindings. I bind the Button content to the CustomButtonEditor's Value Property. This works fine when i set/change the values of every button cell, when the grid is initialised. But i want to add some "default" content and tried to do so by creating a Setter in the editor style that i bind to a field. (This works with i.e. the Background, but not with the Content of the Button)
I do not want to fill each button cell seperately because i have an addnewrow and always want to show a default value (button text or image) when (or before) a new row/record is created. The content should even be shown in the addnewrow!
I hope you understand my problem!
DHPButtonEditor Code:
Imports Infragistics.Windows.Editors <TemplatePart(Name:="PART_DhpButton", Type:=GetType(Button))> _ Public Class DHPButtonEditor Inherits ValueEditor Shared Sub New() DefaultStyleKeyProperty.OverrideMetadata( _ GetType(DHPButtonEditor), _ New FrameworkPropertyMetadata(GetType(DHPButtonEditor))) ClickEvent = EventManager.RegisterRoutedEvent( _ "Click", RoutingStrategy.Bubble, _ GetType(RoutedEventHandler), _ GetType(DHPButtonEditor)) End Sub Public Overrides Sub OnApplyTemplate() MyBase.OnApplyTemplate() Dim button As Button = TryCast(MyBase.GetTemplateChild("PART_DhpButton"), Button) If button IsNot Nothing Then AddHandler button.Click, AddressOf Button_Click End If End Sub Public Shared ReadOnly ClickEvent As RoutedEvent Public Custom Event Click As RoutedEventHandler AddHandler(ByVal value As RoutedEventHandler) Me.AddHandler(ClickEvent, value) End AddHandler RemoveHandler(ByVal value As RoutedEventHandler) Me.RemoveHandler(ClickEvent, value) End RemoveHandler RaiseEvent(ByVal sender As Object, ByVal e As RoutedEventArgs) Me.RaiseEvent(e) End RaiseEvent End Event Private Sub Button_Click(sender As Object, e As RoutedEventArgs) Dim args As New RoutedEventArgs() args.RoutedEvent = ClickEvent Me.RaiseEvent(args) End Sub Public Overrides Function CanEditType(type As Type) As Boolean Return True End Function Public Overrides Function CanRenderType(type As Type) As Boolean Return True End Function End Class
DHPButtonEditor XAML Code (Generic.xaml):
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:ButtonEditorStyleImage"> <Style x:Key="{x:Type local:DHPButtonEditor}" TargetType="{x:Type local:DHPButtonEditor}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:DHPButtonEditor}"> <Button Name="PART_DhpButton" Margin="0" Width="{TemplateBinding Width}" Background="{TemplateBinding Background}" Content="{TemplateBinding Value}"> </Button> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
MainWindow Code:
Imports System.Data Public Class MainWindow Public mTable As New DataTable Public Property Table As DataTable Get Return mTable End Get Set(value As DataTable) mTable = value End Set End Property Public Sub New() InitializeComponent() mTable.Columns.Add("Text", GetType(String)) mTable.Columns.Add("Button", GetType(Object)) For i As Integer = 0 To 4 mTable.Rows.Add("Line " + (i + 1).ToString) 'With this code line i only write button content to records which are 'generated at loading, but not when i add new records after loading: 'mTable.Rows.Add("Line " + (i + 1).ToString, "Not Clicked") Next XamDataGrid1.DataContext = Table.DefaultView End Sub Private Sub Button_Click(sender As Object, e As RoutedEventArgs) Dim b As DHPButtonEditor = TryCast(sender, DHPButtonEditor) b.Value = "Clicked" b.Background = System.Windows.Media.Brushes.Green End Sub End Class
MainWindow XAML Code:
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:igDP="http://infragistics.com/DataPresenter" xmlns:local="clr-namespace:ButtonEditorStyleImage" Title="MainWindow" Height="350" Width="525" > <Grid> <igDP:XamDataGrid Name="XamDataGrid1" DataSource="{Binding}" GroupByAreaLocation="None"> <igDP:XamDataGrid.Resources> <Style x:Key="BtnEditor" TargetType="{x:Type local:DHPButtonEditor}"> <Style.Setters> <Setter Property="Value" Value="Not Clicked" /> <Setter Property="Background" Value="Red" /> <EventSetter Event="Click" Handler="Button_Click" /> </Style.Setters> </Style> </igDP:XamDataGrid.Resources> <igDP:XamDataGrid.FieldLayoutSettings> <igDP:FieldLayoutSettings AutoGenerateFields="False" AutoFitMode="Always" AllowAddNew="True" AddNewRecordLocation="OnBottom" /> </igDP:XamDataGrid.FieldLayoutSettings> <igDP:XamDataGrid.FieldLayouts> <igDP:FieldLayout> <igDP:Field Name="Text" /> <igDP:Field Name="Button"> <igDP:Field.Settings> <igDP:FieldSettings EditorType="{x:Type local:DHPButtonEditor}" EditorStyle="{StaticResource BtnEditor}" /> </igDP:Field.Settings> </igDP:Field> </igDP:FieldLayout> </igDP:XamDataGrid.FieldLayouts> </igDP:XamDataGrid> </Grid> </Window>
Thanks for every help!
Regards,
Jochen
Hello Jochen,
Thank you for your post. I have been looking into it and the code you have provided and I can say that this behavior is expected, because DHPButtonEditor’s Value is null and since the Button Value is bound to it, it’s also null. This happens because after the Style is applied and you set the Editor’s Value to “NotClicked” the Binding between the Editor and the CellValuePresenter is created and since the underlying object is null it overrides the value set in Style. If you want to add default value to the AddNewRecord you can handle the Editor’s Laoded event and check if it in the AddNewRecord and set its value explicitly, which will also become null when edit mode starts because of the Binding. I modified your sample to show you this approach.
Hops this helps you.