{"id":15411625,"url":"https://github.com/dirkster99/inplaceeditboxlib","last_synced_at":"2025-04-19T03:12:12.967Z","repository":{"id":24710118,"uuid":"101417471","full_name":"Dirkster99/InplaceEditBoxLib","owner":"Dirkster99","description":"WPF/MVVM control to implement a textbox on top of other elements like TreeViewItem or ListViewItem (use case: perform in place edit on top of a displayed text item)","archived":false,"fork":false,"pushed_at":"2022-05-12T15:59:42.000Z","size":895,"stargazers_count":41,"open_issues_count":5,"forks_count":15,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-14T23:20:07.992Z","etag":null,"topics":["csharp","dark","dotnet","edit-text-inplace","inplace","inplace-edit","light","modern","mvvm","textbox","themes","ui","ui-components","wpf"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Dirkster99.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-08-25T15:30:53.000Z","updated_at":"2024-10-11T08:17:17.000Z","dependencies_parsed_at":"2022-08-09T02:30:27.626Z","dependency_job_id":null,"html_url":"https://github.com/Dirkster99/InplaceEditBoxLib","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dirkster99%2FInplaceEditBoxLib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dirkster99%2FInplaceEditBoxLib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dirkster99%2FInplaceEditBoxLib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dirkster99%2FInplaceEditBoxLib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dirkster99","download_url":"https://codeload.github.com/Dirkster99/InplaceEditBoxLib/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249191246,"owners_count":21227529,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dark","dotnet","edit-text-inplace","inplace","inplace-edit","light","modern","mvvm","textbox","themes","ui","ui-components","wpf"],"created_at":"2024-10-01T16:49:44.726Z","updated_at":"2025-04-19T03:12:12.943Z","avatar_url":"https://github.com/Dirkster99.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"| NuGet Packages                                                                  | Downloads\n| :------------------------------------------------------------------------------ | :---------------------------------\n| [InplaceEditboxlib](https://www.nuget.org/packages/Dirkster.inplaceeditboxlib)  | [![NuGet](https://img.shields.io/nuget/dt/Dirkster.inplaceeditboxlib.svg)](http://nuget.org/packages/Dirkster.inplaceeditboxlib)\n\n# InplaceEditBoxLib\nWPF/MVVM control to implement a textbox on top of other elements like a\nTreeViewItem or ListViewItem (use case: perform in place edit of a displayed item)\n\n\u003cp\u003e\u003cimg src=\"https://github.com/Dirkster99/InplaceEditBoxLib/blob/master/00_Docu/screenshot.png\" align=\"right\" width=\"500\" \u003e\u003c/p\u003e\n\u003cbr/\u003e\u003cbr/\u003e\u003cbr/\u003e\n\n[![Build status](https://ci.appveyor.com/api/projects/status/7g6bx6uku9e1qow8?svg=true)](https://ci.appveyor.com/project/Dirkster99/inplaceeditboxlib)\n[![Release](https://img.shields.io/github/release/Dirkster99/inplaceeditboxlib.svg)](https://github.com/Dirkster99/inplaceeditboxlib/releases/latest)\n[![NuGet](https://img.shields.io/nuget/dt/Dirkster.inplaceeditboxlib.svg)](http://nuget.org/packages/Dirkster.inplaceeditboxlib)\n\n![Net4](https://badgen.net/badge/Framework/.Net\u0026nbsp;4/blue) ![NetCore3](https://badgen.net/badge/Framework/NetCore\u0026nbsp;3/blue)\n\n\n\n# Use Case: Edit-In-Place\n\nThe edit-in-place text control contained in this project can be used as a base for developing applications where users would like to edit text strings as overlay over the normally displayed string.\n\nThe best and well known example of an edit-in-place text control is the textbox overlay that is used for renaming renaming a file or folder in Windows Explorer. The user typically selects an item in a list (listbox, listview, grid) or structure of items (treeview) and renames the item using a textbox overlay (without an additional dialog).\n\nChange of focus (activation of a different window), pressing escapee leads to canceling of the rename process and pressing enter leads to confirmation of the new string.\n\n# Editing with Text Overlay\nHere is a sequence of screenshots that shows the normal steps when renaming an item with an overlay TextBox control:\n![](https://github.com/Dirkster99/InplaceEditBoxLib/blob/master/00_Docu/00_Docu/EditOverlay/Step1.png)\n\nPress F2 to start renaming\n![](https://github.com/Dirkster99/InplaceEditBoxLib/blob/master/00_Docu/00_Docu/EditOverlay/Step2.png)\n\nType a different sequence of characters\n![](https://github.com/Dirkster99/InplaceEditBoxLib/blob/master/00_Docu/00_Docu/EditOverlay/Step3.png)\n\nPress enter to confirm the new name\n![](https://github.com/Dirkster99/InplaceEditBoxLib/blob/master/00_Docu/00_Docu/EditOverlay/Step4_Result.png)\n\n## Features ##\n\nThis edit-in-place control in this project can be used in the collection of any **ItemsControl** (Treeview, ListBox, ListView etc).\n\nFind more details in CodeProject:\nhttps://www.codeproject.com/Articles/802385/A-WPF-MVVM-In-Place-Edit-TextBox-Control\n\n# Demo in this Repository\nThe demo program shows how the control can be used in a treeview with:\n\n* keybinding - Press F2 to rename - Press ESC to cancel renaming\n\n* Context Menu - Click Rename in context Menu to rename an item\n* Double Click - Double click the text portion to start renaming\n\n**Watch this video on youtube**\nhttps://www.youtube.com/watch?v=iOiveZ214M0\u0026feature=youtu.be\n\nand Handling Errors, such as:\n\n* Renaming with an invalid character (Press ? in Edit Mode to see a pop-up message)\n* Attempting to name 2 items with the same name (Name 2 items 'a' should invoke a pop-up message on the 2nd items rename)\n* Minimum and Maximum length of a name should between 1 - 254 Characters (naming item with empty string '' should invoke a pop-up message)\n\n### Editing text with Text and DisplayText properties ###\n\nThe edit-in-place control has 2 string properties, one is for display (**DisplayText**) and the other (**Text**) string represents the value that should be edited.\n\nThis setup enables application developers to show more than just a name in each item. Each item can, for example, display a name and a number by using the **DisplayText** property, while the **Text** property should contain the string that is to be edit.\n\nThe confirmation of editing does not change either of the above dependency properties. The edit-in-place control executes instead the command that is bound to the **RenameCommand** dependency property to let the viewmodel adjust all relevant strings.\n\nThe view invokes the bound **RenameCommand** and passes the **RenameCommandParameter** as parameter along. \n\n```XML\n\u003cEditInPlace:EditBox Text=\"{Binding Path=DisplayName, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}\"\n  DisplayText=\"{Binding Path=DisplayName,StringFormat={}{0} (File), Mode=OneWay, UpdateSourceTrigger=PropertyChanged}\"\n ToolTip=\"{Binding Description, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}\"\n  Focusable=\"True\"\n\n  VerticalAlignment=\"Stretch\"\n  HorizontalAlignment=\"Left\"\n  IsReadOnly=\"{Binding IsItemReadOnly}\"\n  RenameCommand=\"{Binding Path=Data.RenameCommand, Source={StaticResource DataContextProxy}}\"\n  RenameCommandParameter=\"{Binding}\"\n  ToolTipService.ShowOnDisabled=\"True\"\n      \n  Margin=\"2,0\" /\u003e\n```\nThe actual renaming (changing the data structure and checking for quality issues, such as, minimal length of string, is then performed by the code invoked in the viewmodel. The viewmodel can then choose to show an error notification and refuse the renaming or perform the renaming and close the process (see Demo in [SolutionViewModel.cs](https://github.com/Dirkster99/InplaceEditBoxLib/blob/master/source/SolutionLib/ViewModels/Browser/SolutionViewModel.cs)).\n\n```C++\n// Do we already know this item?\nif (string.IsNullOrEmpty(newName) == true ||\n  newName.Length \u003c 1 || newName.Length \u003e 254)\n{\n    solutionItem.RequestEditMode(RequestEditEvent.StartEditMode);\n    solutionItem.ShowNotification(\"Invalid legth of name\",\n        \"A name must be between 1 and 254 characters long.\");\n    return;\n}\n\nvar parent = solutionItem.Parent;\n\nif (parent != null)\n{\n    // Do we already know this item?\n    var existingItem = parent.FindChild(newName);\n    if (existingItem != null)\n    {\n        solutionItem.RequestEditMode(RequestEditEvent.StartEditMode);\n        solutionItem.ShowNotification(\"Item Already Exists\",\n            \"An item with this name exists already. All names must be unique.\");\n        return;\n    }\n\n    parent.RenameChild(solutionItem, newName);\n\n    // This parent selection + sort + child selection\n    // scrolls the renamed item into view...\n    parent.IsItemSelected = true;\n    parent.IsItemExpanded = true;   // Ensure parent is expanded\n    parent.SortChildren();\n    solutionItem.IsItemSelected = true;\n...\n}\n```\n\n### Initiate Editing Text from the ViewModel ###\n\nThe edit-in-place control expects the viewmodel to implement the **InplaceEditBoxLib.Interfaces.IEditBox** interface which contains a **RequestEdit** event. This event can be fired by the viewmodel to start editing of a given item.\n\n### Initiate Editing Text from the View ###\n\nEditing text from the view can be done directly by 'double click' on the text or via command binding on the viewmodel which invokres the **RequestEdit** event mentioned above.\n\nSee demo project with:\n* Rename context menu item or\n* F2 Key binding\n\n### Usage of Limited Space ###\n\nThe EditBox in-place overlay control should not exceed the view port area of the parent scrollviewer of the items control. That is, the EditBox should not exceed the visible area of a treeview if it was used within a treeview. This rule ensure that users do not end up typing in an invisible area (off-screen) when typing long string in small areas.\n\nThe following sequence of images shows the application behavior when the user enters the string 'The quick fox jumps over the river' in a limited space scenario:\n\n![](https://github.com/Dirkster99/InplaceEditBoxLib/blob/master/00_Docu/00_Docu/SpaceLimits/Step1.png) ![](https://github.com/Dirkster99/InplaceEditBoxLib/blob/master/00_Docu/00_Docu/SpaceLimits/Step2.png)\n![](https://github.com/Dirkster99/InplaceEditBoxLib/blob/master/00_Docu/00_Docu/SpaceLimits/Step1.png) ![](https://github.com/Dirkster99/InplaceEditBoxLib/blob/master/00_Docu/00_Docu/SpaceLimits/Step4.png)\n ![](https://github.com/Dirkster99/InplaceEditBoxLib/blob/master/00_Docu/00_Docu/SpaceLimits/Step5_Result.png)\n\n### Cancel and Confirm ###\n\n* Editing text with the edit-in-place control can be canceled by pressing the 'Esc' key or changing the input focus to another windows or control. The application shows the text as it was before the editing started.\n\n* Editing text can be confirmed pressing the enter key. The application shows the entered text instead of the text before the editing started.\n\n* Clicking on the background of the ItemsControl (TreeView, ListView etc) cancels the edit mode (thanks to Alaa Ben Fatma for useful hints).\n\n### IsReadOnly property ###\n\nThe edit-in-place control supports a Boolean **IsReadonly** dependency property to lock individual items from being renamed. Default is **false** meaning every item is editable unless binding defines somtheing else.\n\n### IsEditableOnDoubleClick ###\n\nEditing the string that is displayed with the edit-in-place control can be triggered with a time 'double click'.\nThis double click can be configured to occur in a certain time frame. There are 2 double dependency properties that can be setup to consume only those double clicks with a time frame that is larger than **MinimumClickTime** but smaller than **MaximumClickTime**.\n\nDefault values for **MinimumClickTime** and **MaximumClickTime** are 300 ms and 700 ms, respectively.\n\nThe **IsEditableOnDoubleClick** boolean dependency property can be setup to dermine whether double clicks are evaluated for editing or not. Default is true.\n\n### IsEditing property ###\n\nThe edit-in-place control supports a **one way** Boolean **IsEditing** dependency property to enable viewmodels to determine whether an item is currently edited or not. This property cannot be used by the viewmodel to force the view into editable mode (since it is a get only property in the view). Use the **RequestEdit** event defined in **InplaceEditBoxLib.Interfaces.IEditBox** to request an edit mode that is initialized by the viewmodel.\n\n### Key Filter and Error Handling ###\n\nThe EditBox control contains properties that can be used to define a blacklist of characters that should not be input by the user. See properties:\n\n- **InvalidInputCharacters**\n- **InvalidInputCharactersMessage**\n- **InvalidInputCharactersTitle**\n\nThe control implements a pop-up message element to show hints to the user if he types invalid characters.\n\n![](https://github.com/Dirkster99/InplaceEditBoxLib/blob/master/00_Docu/00_Docu/ErrorHandling/PopUpMessage.png?raw=true)\n\n## Known Limitations ##\n\n- Key definitions entered in the in-place textbox cannot be defined through a white-list. The textbox does not support input masks.\n\n- Restyling TextBox with Hyperlink does not work since a Hyperlink is stored in the InlineCollection of a TextBox. But an InlineCollection cannot be set via dependency property and I cannot seem to work around this with a custom dependency property.\n\n# Credits #\n\n- Thanks to Joseph Leung for coaching me along the way\n\n- This code uses part of ATC Avalon Team's work:\nhttp://blogs.msdn.com/atc_avalon_team/archive/2006/03/14/550934.aspx\n\n- CodeProject Article \"Editable TextBlock in WPF for In-place Editing\"\nhttp://www.codeproject.com/Articles/31592/Editable-TextBlock-in-WPF-for-In-place-Editing?fid=1532208\u0026df=90\u0026mpp=25\u0026noise=3\u0026prof=False\u0026sort=Position\u0026view=Normal\u0026spc=Relaxed\u0026fr=26#xx0xx\n\n## Theming\n\nCheck theming here:\n- [FileExplorer in Edi](https://github.com/Dirkster99/Edi/wiki/File-Explorer-Tool-Window)\n- [MLib](https://github.com/Dirkster99/MLib)\n\nLoad *Light* or *Dark* brush resources in you resource dictionary to take advantage of existing definitions.\n\n```XAML\n    \u003cResourceDictionary.MergedDictionaries\u003e\n        \u003cResourceDictionary Source=\"/InplaceEditBoxLib;component/Themes/DarkBrushes.xaml\" /\u003e\n    \u003c/ResourceDictionary.MergedDictionaries\u003e\n```\n\n```XAML\n    \u003cResourceDictionary.MergedDictionaries\u003e\n        \u003cResourceDictionary Source=\"/InplaceEditBoxLib;component/Themes/LightBrushes.xaml\" /\u003e\n    \u003c/ResourceDictionary.MergedDictionaries\u003e\n```\n\nThese definitions do not theme all controls used within this library. You should use a standard theming library, such as:\n- [MahApps.Metro](https://github.com/MahApps/MahApps.Metro),\n- [MLib](https://github.com/Dirkster99/MLib), or\n- [MUI](https://github.com/firstfloorsoftware/mui)\n\nto also theme standard elements, such as, button and textblock etc.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdirkster99%2Finplaceeditboxlib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdirkster99%2Finplaceeditboxlib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdirkster99%2Finplaceeditboxlib/lists"}