WPF Thoughts
Wednesday, October 9, 2024
How to make Text Boxes ReadOnly when their container is Disabled
Tuesday, October 1, 2024
Breaking the IsEnabled inheritance
One useful feature of WPF is that when you disable a container, all the controls in that container are disabled too. So if you want to put a page into read-only mode, you just have to disabled the page. The upside is simplicity and security. The downside to this is that there are probably some buttons you want the user to be able to click on.
The common technique to get around this is to put the buttons in a different container. However, this does not solve the problems associated with grids, lists, multi-line text boxes and other controls that need to respond to user interactions without allowing the user to edit them.
I read an interesting response to a question on StackOverflow see the first answer here https://stackoverflow.com/questions/14584662/enable-a-child-control-when-the-parent-is-disabled. It struck me as a very clever solution and definitely not a hack. I rewrote it in Visual Basic and created a full solution.
The idea is to wrap a component that should inherits its parent IsEnabled property in a container that breaks that inheritance. It's really quite elegant.
Start a WPF, VB, .Net Framework Visual Studio project and call it BreakEnabledInheritance. It should work for .Net Core just as well.
Add a class called BreakEnabledInheritanceContainer. The code is very simple.
This approach has the advantage that the preferred solution (controls inherit their parent's IsEnabled) can be used for most controls and we can override that functionality for selected controls. This reduces the chance of a developer accidently enabling a control that should be disabled and vice versa.
Displaying browsing history
I came across a good article that explains how to access a browser's recent history but it is written in C++ for some reason. I wanted to see how to do it using C# so I wrote this project. The original article is at https://www.codeproject.com/Articles/5388718/Displaying-recent-browsing-history If you don't subscribe to the CodeProject newsletters you can subscribe at https://www.codeproject.com/Feature/Insider/
You will need SQLite and also the .Net wrapper. Start a new WPF C# .NetCore project in Visual Studio and call it BrowserHistory. I'm going to display the Edge browser history but if you read the original article you can see how to easily modify the project to display the Chrome history.
Using Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution, select Browse and search for SQLite (only one L). Install it. Now search for System.Data.SQLite and install that. Your solution looks like this.
Next we will write the XAML. Alter MainWindow.xaml to look like this. It defines a datagrid that binds to a property called dtHistory.
Now we can work on the fun stuff. The steps are.
- Find the browser history
- Make a copy (because the browser may have the original locked)
- Read parts of the browser history into a data table
- Convert microseconds since 1/1/1601 into a date time so we can display it
Tuesday, September 24, 2024
DataColumn AutoIncrement - sequence of events does matter
I spent quite a while today trying to figure out some bizarre behavior in the DataTable.NewRow method.
I have a data table with 4 rows in it. One of the columns is the primary key and has AutoIncrement turned on. The Seed and Step are both -1. When I add a new row, I expect the primary key to be set to -1. This isn't happening. It's setting the primary key to one less than the maximum value in the existing rows. Let me show you with a simple example.
Friday, August 9, 2024
FODY
The Problem
I spent some time looking at ways to reduce all the repetitive property declarations required for MVVM. So have a lot of other people, most of whom are far smarter than me.
The Community Toolkit looked very promising.
But even though it claims to work in VB and .Net Framework it does not. No errors, no warnings, no binding errors, modifying properties in controls does not update the bound properties. So that's a shame.
The good news
One of my colleagues recommend FODY - a GitHub project that claims to work for VB in .Net Framework. OK - I'm game. I put together the most trivial project I could think of. We have our ViewModels in our code-behind, we use VB, and we're still on .Net Framework. Yes, we're practically Neanderthal.
FODY is much bigger than simply providing MVVM functionality. It's a framework for all sorts of things. The specific package I need is called PropertyChanged.Fody. Let's get started then.
In Visual Studio 2022 create a WPF, VB, .NetFramework project called FODY
In the menu select Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution...
Click the Browse tab and search for FODY
Install Fody and PropertyChanged.Fody into your solution. Your packages.config will look something like this.