Silverlight / WPF - how to eliminate the entry of string within the silverlight datagrid

Asked By Ramachandran on 25-Jun-12 02:22 AM
Earn up to 40 extra points for answering this tough question.
I am using silverlight datagrid in this only integer numbers and decimal numbers to be entered and string values are to be eliminated how to do i have tried on stringformat { ###.##} on the datagrid value field.... this is my xaml code.



 <sdk:DataGridTextColumn Header="Jan" Binding="{Binding Jan,Mode=TwoWay,StringFormat=\{0:d\}}"  CanUserReorder="True" CanUserResize="True" CanUserSort="True" Width="80">
                  <sdk:DataGridTextColumn.CellStyle  >
                    <Style TargetType="sdk:DataGridCell" >
                      <Style.Setters>
                        <Setter Property="HorizontalAlignment" Value="Right" />
                      </Style.Setters>
                    </Style>
                  </sdk:DataGridTextColumn.CellStyle>
                </sdk:DataGridTextColumn>
Jitendra Faye replied to Ramachandran on 26-Jun-12 12:56 AM
Try to use DataGridTemplateColumn.

Here you can use  NumericTextBox in DataGridTemplateColumn.CellEditingTemplate.



Try this and let me know.
Jitendra Faye replied to Ramachandran on 26-Jun-12 12:57 AM
Or if you want to do it by code then refer this links-

http://social.msdn.microsoft.com/Forums/hi-IN/wpf/thread/02099f48-7673-4fd0-a74d-605769e21a7d

Here you will get example for it.


Vikram Singh Saini replied to Ramachandran on 26-Jun-12 09:16 AM
Hello Ramachandran,

For your requirement, I created demo application and tested the solution by picking code guidance from http://social.msdn.microsoft.com/Forums/hi-IN/wpf/thread/02099f48-7673-4fd0-a74d-605769e21a7d. But the code line

txt.CaretIndex = txt.Text.Length; // TextBox doesn't contains definition for 'CaretIndex'

didn't worked successfully. I researched and tried lot for it but no luck. So the concerned code failed upto some extent.  So I created alternative solution for same using idea from there for objective 2.

Objectives Achieved:

(1) Remove string values on data bind.
If your database column contains string and numeric value both such as 9s.

(2) Only numeric values are allowed during editing.
When user type some text in TextBox they are can type both numeric and string values but only numeric values are returned to them in TextBox. In short, the TextBox behave as Numeric TextBox.

**************   REMOVE STRING VALUES ON DATA BIND **************

Before I start dwelling in actual code, allow me to share with you .xaml file structure for better understanding. Here:

<UserControl x:Class="SL_DataGrid_WCF.MainPage"

    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"

    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"

    mc:Ignorable="d"

    d:DesignHeight="300" d:DesignWidth="400">

 

    <sdk:DataGrid AutoGenerateColumns="False" HorizontalAlignment="Left" Margin="341,21,0,0" Name="myDataGrid"

          VerticalAlignment="Top" LoadingRow="myDataGrid_LoadingRow">

      <sdk:DataGrid.Columns>

        <sdk:DataGridTemplateColumn Header="ItemNumber" Width="Auto">

          <sdk:DataGridTemplateColumn.CellTemplate>

            <DataTemplate>

              <TextBox Text="{Binding ItemNumber}" Foreground="Green" VerticalAlignment="Center" x:Name="tb"

                   Loaded="tb_Loaded" TextChanged="tb_TextChanged"/>

            </DataTemplate>

          </sdk:DataGridTemplateColumn.CellTemplate>

          <sdk:DataGridTemplateColumn.CellEditingTemplate>

            <DataTemplate>

              <TextBox Text="{Binding ItemNumber, Mode=TwoWay}" />

            </DataTemplate>

          </sdk:DataGridTemplateColumn.CellEditingTemplate>

        </sdk:DataGridTemplateColumn>

        <sdk:DataGridTextColumn CanUserReorder="True" CanUserSort="True" Width="Auto" Binding="{Binding ItemDescription}"

          Header="ItemDescription"/>

        <sdk:DataGridTextColumn CanUserReorder="True" CanUserSort="True" Width="Auto" Binding="{Binding Quantity}"

          Header="Quantity"/>

      </sdk:DataGrid.Columns>

    </sdk:DataGrid>

</UserControl>

 


The first column ItemNumber contains text values as 9S, AI2 and so on. As you can notice we have used Loaded event handler, that would run after controls have been initialized and loaded. So in same we would check TextBox values & extract numbers from it. Code here (in .xaml.cs):

      // Fires after control loaded

      private void tb_Loaded(object sender, RoutedEventArgs e)

      {

        TextBox txtBox = sender as TextBox;      

 

        string numbers = ExtractNumbers(txtBox.Text.ToString());

 

        if (!String.IsNullOrEmpty(numbers))        

          txtBox.Text = numbers;

      }       

 

      // Returns integer or double (no string)

      static string ExtractNumbers(string input)

      {

        string numberInText = null;

        numberInText = string.Join(null, System.Text.RegularExpressions.Regex.Split(input, "[^.\\d]"));

        return numberInText;

      }


Now the first column in DataGrid would show only numeric values.

**************   ONLY NUMERIC VALUES ARE ALLOWED DURING EDITING **************

For this objective we have used the suggestion from the link: http://social.msdn.microsoft.com/Forums/hi-IN/wpf/thread/02099f48-7673-4fd0-a74d-605769e21a7d as shared by Vickey F.

But the code part that was used for refusing string values in the link code has been modified by me as it was not working. We have used TextChanged event handler of TextBox (See .xaml code above). Here is the TextChanged EventHandler code:

private void tb_TextChanged(object sender, TextChangedEventArgs e)

      {

        TextBox txt = sender as TextBox;

        if (txt != null)

        {

          txt.Text = ExtractNumbers(txt.Text);

        }

      }     

 

      // Returns integer or double (no string)

      static string ExtractNumbers(string input)

      {

        string numberInText = null;

        numberInText = string.Join(null, System.Text.RegularExpressions.Regex.Split(input, "[^.\\d]"));

        return numberInText;

      }


So now whenever user types in the first column of the DataGrid, he/she would only see numeric values (no string values).

Do let us know if left any questions or doubts.