locked
change TextBlock into TextBox after click on button RRS feed

  • Question

  • Hey there..

    I'm searching for a solution to change TextBlocks into TextBoxes.

    My App has a Grid with five TextBlocks in which data of a selected item is shown. After clicking on the AppBarButton "Change" the user should be able to change the existing data in the TextBox.

    Afterwards the data should be save.

    Would be nice if someone could help me..

    Andi

    Monday, August 20, 2012 6:54 AM

Answers

  • Here is a small sample for you:

    Put this into your XAML empty page:

        <Grid x:Name="LayoutRoot" Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <Grid.RowDefinitions>
                <RowDefinition Height="0.3*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup>
                    <VisualState x:Name="ReadOnly">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="textBox1" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="textBlock1" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Editable">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="textBox1" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="textBlock1" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            
            <TextBlock x:Name="textBlock1"  Grid.Row="0" Text="SAMPLE TEXT" Visibility="Collapsed" />
            <TextBox x:Name="textBox1"  Grid.Row="0" Text="SAMPLE TEXT" Visibility="Collapsed"/>
            
            <Button x:Name="Edit" Grid.Row="2" Click="OnEditClicked" Content="Switch States" />
        </Grid>
    

    And use this as a sample codebehind:

            bool b = false;
            private void OnEditClicked(object sender, RoutedEventArgs e)
            {
                string state = b?"ReadOnly":"Editable";
                VisualStateManager.GoToState(this, state, false);
                b = !b;
            }
    By default i've defined both TextBlock and TextBox to be Collapsed for the further effect.

    LinkedIn Profile
    SharePoint Advanced Visibility Options project
    SharePoint Managed Metadata Claims Provider project

    • Proposed as answer by HeToC Monday, August 20, 2012 4:43 PM
    • Marked as answer by afroDeluXe Tuesday, August 21, 2012 9:54 AM
    • Unmarked as answer by afroDeluXe Wednesday, August 22, 2012 8:38 AM
    • Marked as answer by afroDeluXe Wednesday, August 22, 2012 11:21 AM
    Monday, August 20, 2012 12:13 PM
  • If I do it this way the function works how I want:

    - change the positions in string state = ... read/edit depending on the state

    - reset the isButtonRaiseEvent in every ButtonClick event

            bool isButtonRaiseEvent = false;
    
            
            void ButtonEdit_Click(object sender, RoutedEventArgs e)
            {
                string state = isButtonRaiseEvent ? "VisualStateRead" : "VisualStateEdit";
                VisualStateManager.GoToState(this, state, false);
                isButtonRaiseEvent = !isButtonRaiseEvent;
    
                ButtonAdd.Visibility = .....
    
                this.itemListView.IsEnabled = false;
    
                isButtonRaiseEvent = false;
            }
    
    
            async void ButtonSave_Click(object sender, RoutedEventArgs e)
            {
                var dialog = new Windows.UI.Popups.MessageDialog("data saved");
                await dialog.ShowAsync();
    
                string state = isButtonRaiseEvent ? "VisualStateEdit" : "VisualStateRead";         //changed
                VisualStateManager.GoToState(this, state, false);
                isButtonRaiseEvent = !isButtonRaiseEvent;
    
                ButtonAdd.Visibility = .....
    
                this.itemListView.IsEnabled = true;
    
                isButtonRaiseEvent = false;
            }
    

    Or you think there will be a problem eventually!?

    • Marked as answer by afroDeluXe Wednesday, August 22, 2012 11:21 AM
    Wednesday, August 22, 2012 11:21 AM

All replies

  • You can place 2 controls within the same Grid cell: a TextBlock and a TextBox, and in order to specify their visibility properties, just add a VisualStates and toggle em within your AppBar button code.

    eg:

    <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="EditableGridVisualStateGroup">
                    <VisualState x:Name="ReadOnly">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="textBox1" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="textBlock1" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Editable">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="textBox1" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="textBlock1" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
    	</VisualStateGroup>
    </VisualStateManager.VisualStateGroups>


    LinkedIn Profile
    SharePoint Advanced Visibility Options project
    SharePoint Managed Metadata Claims Provider project

    Monday, August 20, 2012 7:04 AM
  • hm.. okay, this sounds logical.. thank you :)

    but so, the two fields (... with the "same" input ) must have different names - right!?

    But I want to get the data (seen in the TextBlock) from a database. After clicking the ChangeButton and editing the data in the TextBox I want to save/ overwrite it in the database.

    Won't this be a problem with implementation because of the different names and the bindings!?



    • Edited by afroDeluXe Monday, August 20, 2012 9:02 AM
    Monday, August 20, 2012 8:51 AM
  • Hi,

    there 'll be no problem at all if you're using MVVM pattern, just bind TextBox1 and TexBlock1 to the same Property (just ensure TextBox1 has a TwoWay binding defined)


    LinkedIn Profile
    SharePoint Advanced Visibility Options project
    SharePoint Managed Metadata Claims Provider project

    Monday, August 20, 2012 9:22 AM
  • Ah okay.. i'll try it.

    In the *CS code: How is the best way to implement the ButtonClick? How could I activate the whole VisualState "Editable". It would be needless if I do it this way..

    private bool isButtonRaiseEvent = false; void ButtonEdit_Click(object sender, RoutedEventArgs e) { isButtonRaiseEvent = true; TextBox1.Visibility = Windows.UI.Xaml.Visibility.Visible; TextBlock1.Visibility = Windows.UI.Xaml.Visibility.Collapsed;

    ... }


    • Proposed as answer by sunraybrett Monday, August 20, 2012 10:14 AM
    • Unproposed as answer by sunraybrett Monday, August 20, 2012 10:14 AM
    Monday, August 20, 2012 9:52 AM
  • EditButton impl:

    IMO The best way is to activate certain visual state instead of setting up Visibility properties on dozens controls:

    VisualStateManager.GoToState(theGridControlHostingDozensOfTextBlockAndBoxes, "ReadOnly", false);

    Aldo your "Editable" visual state should make Commin button editable to invoke an appropriate action of the View Model committing changes to the database.


    LinkedIn Profile
    SharePoint Advanced Visibility Options project
    SharePoint Managed Metadata Claims Provider project


    • Edited by HeToC Monday, August 20, 2012 10:16 AM
    Monday, August 20, 2012 10:14 AM
  • If you want to do it in the Code behind then:

    IsEditable = !IsEditable

    VisualStateManager.GoToState(this, isEditMode ? "Editable" : "ReadOnly, false)

    personally I would attach a command handler to invoke the State Change.


    Brett Styles

    Monday, August 20, 2012 10:19 AM
  • hm.. sorry, i dont't get it :/

    If I replace

                TextBox1.Visibility = Windows.UI.Xaml.Visibility.Visible;
                TextBlock1.Visibility = Windows.UI.Xaml.Visibility.Collapsed;

    with

                VisualStateManager.GoToState(itemDetail, "Editable", false);

    there is no changes after clicking on the EditButton.. Or what else I have to change!?

    itemDetail should be the grid, where all the TextBoxes & -Blocks painted or what?

    Monday, August 20, 2012 11:05 AM
  • Here is a small sample for you:

    Put this into your XAML empty page:

        <Grid x:Name="LayoutRoot" Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <Grid.RowDefinitions>
                <RowDefinition Height="0.3*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup>
                    <VisualState x:Name="ReadOnly">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="textBox1" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="textBlock1" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Editable">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="textBox1" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="textBlock1" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            
            <TextBlock x:Name="textBlock1"  Grid.Row="0" Text="SAMPLE TEXT" Visibility="Collapsed" />
            <TextBox x:Name="textBox1"  Grid.Row="0" Text="SAMPLE TEXT" Visibility="Collapsed"/>
            
            <Button x:Name="Edit" Grid.Row="2" Click="OnEditClicked" Content="Switch States" />
        </Grid>
    

    And use this as a sample codebehind:

            bool b = false;
            private void OnEditClicked(object sender, RoutedEventArgs e)
            {
                string state = b?"ReadOnly":"Editable";
                VisualStateManager.GoToState(this, state, false);
                b = !b;
            }
    By default i've defined both TextBlock and TextBox to be Collapsed for the further effect.

    LinkedIn Profile
    SharePoint Advanced Visibility Options project
    SharePoint Managed Metadata Claims Provider project

    • Proposed as answer by HeToC Monday, August 20, 2012 4:43 PM
    • Marked as answer by afroDeluXe Tuesday, August 21, 2012 9:54 AM
    • Unmarked as answer by afroDeluXe Wednesday, August 22, 2012 8:38 AM
    • Marked as answer by afroDeluXe Wednesday, August 22, 2012 11:21 AM
    Monday, August 20, 2012 12:13 PM
  • yeaaa.. thank you very much - this Looks very good! I had a stupid mistake in the codebehind!

    Could you also explain, what you mean with the TwoWay-Binding!?

    Monday, August 20, 2012 3:20 PM
  • By default binding is used to transfer data from Model to the UI element,

    but if you need properties value to be transferred both to the UI element and if UI element changes its value automatically transfer it to the Model you need to specify Two-Way binding.

    Sorry for my English,

    here is a great article if you're not keen of general XAML data bindings . And there is a sample binding app.


    LinkedIn Profile
    SharePoint Advanced Visibility Options project
    SharePoint Managed Metadata Claims Provider project

    Monday, August 20, 2012 4:42 PM
  • Ah, okay.. I will have a look! Much thanks for your help!

    Tuesday, August 21, 2012 9:55 AM
  • Hey.. I have a following problem with the implementation..

    My App has the buttons EDIT, SAVE & DISCARD - they all affect the TextBox-TextBlock-Change.

    Click on a Item --> TextBlocks are shown --> Click on EDIT --> TextBoxes --> Click on SAVE or DISCARD --> Textblocks

    Click on another Item --> TextBlocks --> Click on EDIT -->   ........

    How could I reset the state after clicking on a Item!?

    For every button I have defined an own isButtonRaiseEvent..

            bool isButtonRaiseEvent1 = false;
            void ButtonEdit_Click(object sender, RoutedEventArgs e)
            {
                string state = isButtonRaiseEvent1 ? "VisualStateRead" : "VisualStateEdit";
                VisualStateManager.GoToState(this, state, false);
                isButtonRaiseEvent1 = !isButtonRaiseEvent1;
    
                ButtonDiscard.Visibility = Windows.UI.Xaml.Visibility.Visible;
                ButtonEdit.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                ButtonSave.Visibility = Windows.UI.Xaml.Visibility.Visible;
            }

    I hope you could help me again..


    • Edited by afroDeluXe Wednesday, August 22, 2012 8:39 AM
    Wednesday, August 22, 2012 8:38 AM
  • Hi,

    Are you trying to implement Edit\Save\Discard behavior for each ListItem within the ListView ?


    LinkedIn Profile
    SharePoint Advanced Visibility Options project
    SharePoint Managed Metadata Claims Provider project

    Wednesday, August 22, 2012 8:56 AM
  • Hi again :)

    Yes, I should be possible to edit/save/discard every item in every list..

    Wednesday, August 22, 2012 9:43 AM
  • Easy Impl: If you want to make each item editable, then I can recommend you to create custom control to be used inside your ListBox's ItemTemplate.

    Hard Impl: You may try to create Custom ItemContainerStyle (with new Visual State Group defined) and Custom ItemTemplate... but i'm not sure it is the best way in terms of architecture.

    So I vote for the first approach.

    "Keep It Simple ..."


    LinkedIn Profile
    SharePoint Advanced Visibility Options project
    SharePoint Managed Metadata Claims Provider project

    • Edited by HeToC Wednesday, August 22, 2012 10:45 AM
    Wednesday, August 22, 2012 10:27 AM
  • If I do it this way the function works how I want:

    - change the positions in string state = ... read/edit depending on the state

    - reset the isButtonRaiseEvent in every ButtonClick event

            bool isButtonRaiseEvent = false;
    
            
            void ButtonEdit_Click(object sender, RoutedEventArgs e)
            {
                string state = isButtonRaiseEvent ? "VisualStateRead" : "VisualStateEdit";
                VisualStateManager.GoToState(this, state, false);
                isButtonRaiseEvent = !isButtonRaiseEvent;
    
                ButtonAdd.Visibility = .....
    
                this.itemListView.IsEnabled = false;
    
                isButtonRaiseEvent = false;
            }
    
    
            async void ButtonSave_Click(object sender, RoutedEventArgs e)
            {
                var dialog = new Windows.UI.Popups.MessageDialog("data saved");
                await dialog.ShowAsync();
    
                string state = isButtonRaiseEvent ? "VisualStateEdit" : "VisualStateRead";         //changed
                VisualStateManager.GoToState(this, state, false);
                isButtonRaiseEvent = !isButtonRaiseEvent;
    
                ButtonAdd.Visibility = .....
    
                this.itemListView.IsEnabled = true;
    
                isButtonRaiseEvent = false;
            }
    

    Or you think there will be a problem eventually!?

    • Marked as answer by afroDeluXe Wednesday, August 22, 2012 11:21 AM
    Wednesday, August 22, 2012 11:21 AM
  • Don think there'll be problems, but i'm not professional WinRT developer, I do it on my spare time only.

    ps: a little hint - you can update visual states to update Buttons visibility properties too, so you can skip visibility related code in your .cs files


    LinkedIn Profile
    SharePoint Advanced Visibility Options project
    SharePoint Managed Metadata Claims Provider project

    Wednesday, August 22, 2012 11:52 AM
  • Ah,okay.. this sounds more comfortable.. But I have to look if I have time to memorize this theme or if the functions will work so, too.

    thanks a lot!

    Wednesday, August 22, 2012 1:16 PM