|
title: Put the knife down and take a green herb, dude. |
descrip: One feller's views on the state of everyday computer science & its application (and now, OTHER STUFF) who isn't rich enough to shell out for www.myfreakinfirst-andlast-name.com Using 89% of the same design the blog had in 2001. |
|||||||||||||||
|
FOR ENTERTAINMENT PURPOSES ONLY!!!
Back-up your data and, when you bike, always wear white. As an Amazon Associate, I earn from qualifying purchases. Affiliate links in green. |
||||||||||||||||
|
x
MarkUpDown is the best Markdown editor for professionals on Windows 10. It includes two-pane live preview, in-app uploads to imgur for image hosting, and MultiMarkdown table support. Features you won't find anywhere else include...
You've wasted more than $15 of your time looking for a great Markdown editor. Stop looking. MarkUpDown is the app you're looking for. Learn more or head over to the 'Store now! |
||||||||||||||||
| Thursday, March 26, 2026 | ||||||||||||||||
|
From github.com:
This is an exceptionally important announcement, though it's one I've been predicting for a while. StackOverflow is dead, and the bots sucked up all of its knowledge, and GitHub repos' knowledge, and MSDN's knowledge, and... And we wondered how AI would continue progressing if there was no reason to keep posting answers to the net "for free". But it was obvious. Now each AI engine is storing (will soon be storing?) the answer to each question in its own StackOverflow, so to speak, but one tuned for AI, not humans. Every time you give Copilot the thumbs up or positive feedback (or some other way it figures you likely used its code), it's going to file that away as "The Right Answer for You". You have your own Jon Skeet in your workstation in exchange for your answers being in their own paywalled database. (Not that there's anything inherently wrong with wanting to make a buck.) If all the best programmers use Claude going forward, guess where the best answers are going to come from? Or, as it looks like Copilot wants to do, what if all the best answers are stored in Copilot's corpus? Then regardless of which model you use, the best answers (and autogenerated code) to the questions (and prompts that implicitly ask those questions) that used to go to StackOverflow will come from Copilot. That's what's next, folk. Actually, that's what's now. All the knowledge that you helped build if you leave that setting on its default will be behind a paywall. There's a great podcast with Nilay Patel and the CEO of Grammarly where Patel essentially asks: "Okay, [very not] cool, you're using my name and ostensibly my style. How much are you going to pay me for that?" (Though I suppose the opposite is, "You're happily paying $10/mth for Copilot now. You think you could even sniff that magic without contributing your labor? You'd still be posting to StackOverflow, hoping someone would be kind enough to post something useful back, which used to be amazingly common, but when's the last time that's happened for you?" It's an interesting counterpoint. Perhaps we should unionize before they alter the deal any further, like making it $75/mth. Or $175. Or more. Because they could.) Every so often go out to the middle of the woods, turn off WiFi and cellular, and make sure you can still code. And then realize that's not really your job any more. Labels: ai, business, coding, labor, stackoverflow posted by Jalindrine at 3/26/2026 10:45:00 AM |
||||||||||||||||
| Wednesday, June 07, 2023 | ||||||||||||||||
|
Though so far I hate all the forced unwrapping .NET requires with nullables now -- which was stolen directly from Swift -- this comment on a Skeet answer explaining them a bit, authored by someone you should recognize if you can spell C#, includes one of the most important concepts I've been trying to PR into coworkers for quite a while. Not sure I've ever said it this eloquently, though, so... Here's that key point from Eric Lippert (emphasis mine):
(This might be that Coverity stuff he's talking about. Not sure.) One place I run into disconnects between code and intent routinely is with Jasmine tests. If tests essentially share the exact same code across (Actually I expect a method even for the slightly different ones -- especially for the slightly different ones, because then you can have parameters communicating what's different in the calls out. Make sense? It's all about the DRYing, folks.) Tell me what the tests do by grouping same and different, keeping things DRY so I can get familiar with concepts you're using over and over -- in ways I can't when you just cut and paste code all over the place. Put more succinctly, I hate cut and pasted code because I expect code blocks that seem similar to be slightly different. Otherwise why not DRY them? Because unDRYed code means we've got some code blocks that are exactly the same mixed with some that aren't with no easy, scannable way to tell which is which. Another domain that suffers is checking for strict equality against That is, unless it makes the code worse, follow conventions! When we're in JavaScript land, because it's a dynamic language, I always assume we prefer operating with a truthy/falsy mindset. If you're comparing to a specific value (or If your anti-patterns aren't "evidence of your beliefs", we're doing it wrong! And if we don't share patterns, we should talk about it until we do -- or at least understand each other's dialects. /rant posted by ruffin at 6/07/2023 09:54:00 AM |
||||||||||||||||
| Friday, July 09, 2021 | ||||||||||||||||
|
You should not have a giant, monolithic application. Monolithic codebases are the mind-killers. They are the little-deaths that bring total obliteration. Face your monolith. Allow it to pass over you and through you... ... into a well-modularized codebase. But here's the corollary nobody links to this practice: The best modularization requires smart denormalization and repetition. You catch some of this when you hear about microservices, which hold down the other end of the spectrum from monoliths. I think it's largely because of their association with NoSQL, where being comfortable with denormalizing schemas is absolutely essential. I don't want to get too deep into NoSQL right now, but the concept is the same: To be most nimble in a modularized codebase requires that you -- and it's nearly against my programming north star to admit it -- Repeat Yourself. And that's okay. If you have one service that calls another, and you need to massage your payload, you may have to change it two places, the caller and the server. THIS IS FINE, NO MEME-MIC DOG & FIRE SHOW REQUIRED. Because you know what's worse than changing a model two places? Changing it three places.
Those last two are too often nontrivial. Perhaps they should be trivial, but in practice they almost never are. There's always some argument that 1. requires a breaking change to the shared library, which requires we up its major version, and 2. & 3. are set to update automatically on minor changes, but not major changes, and now we have to redeploy in just the right order so that the other apps that depend on the library in 1. aren't brought down when we... I see you over there. You get it. This has happened to you too. What were we hoping to save ourselves from again? Exactly this sort of tedium. Except now it's even worse than it was before in the monolith! Look, you should be coding the caller and server defensively anyhow, as independent services. The payloads for both, once serialized, are probably coming across the wire as XML or JSON (please JSON) anyhow, so it's not like these model abstractions are necessary beasts. Why do we have to point them both to the same library to have a source of truth? We're comfortable consuming third party apps without sharing model definitions, and that's [at least partially] the setup you chose when you went to modular services. Treat each app as an independent development and change the model twice -- or, when appropriate, add a new model to one with a new API endpoint to maintain backwards compatibility with other consumers. Denormalization between apps at the point of the interface is a-ok. I'm requesting foo. You're sending foo. Having two copies of foo, one for me and one for you, is fine. Even having a slightly different foo for each is often fine as long as the middle of the Venn is what the transaction in question is worried about. No, for real. It's okay. Really. You'll thank me later. posted by ruffin at 7/09/2021 05:03:00 PM |
||||||||||||||||
| Friday, February 26, 2021 | ||||||||||||||||
|
Here's my reply, edited a little, to a recent code review where I got taken to the woodshed for using the underscore prefix for private variables in es5 JavaScript code used in an AngularJS project. Stick around until the end. Spoiler: A, um, widely recognized AngularJS style guide author agrees with me.
I'm biased, but well said. Though, again, this is why I hate working in dated codebases. The code doesn't rust, but it kinda feels like your career is stuck in an episode of Doctor Who. Labels: coding, javascript, style posted by ruffin at 2/26/2021 10:03:00 AM |
||||||||||||||||
| Saturday, August 22, 2020 | ||||||||||||||||
That is the sorry reality of the bazaar Raymond praised in his book: a pile of old festering hacks, endlessly copied and pasted by a clueless generation of IT "professionals" who wouldn't recognize sound IT architecture if you hit them over the head with it. It is hard to believe today, but under this embarrassing mess lies the ruins of the beautiful cathedral of Unix, deservedly famous for its simplicity of design, its economy of features, and its elegance of execution. Labels: coding posted by Jalindrine at 8/22/2020 02:42:00 PM |
||||||||||||||||
| Saturday, November 24, 2018 | ||||||||||||||||
|
From an introduction to Swift I find myself reading today:
Huh?!! Then what’s the point? We’re far enough along in 2018 that a language could have come with forced linting. The compile-time error should be, “Use of a force unwrap on an optional without a nil check is not allowed.” I’ll admit I’m glad Swift exists. I thought it’d be fun to research SpriteKit and hack up a quick 2D game to relax, and Objective-C looks a little bit more of a head rethread than my usual [stolen] line that “all programming languages are just dialects of the same language”. But it’s a pain that Swift’s Linters ftw, imo. posted by ruffin at 11/24/2018 04:16:00 PM |
||||||||||||||||
| Monday, April 23, 2018 | ||||||||||||||||
|
From Erich Reich at qmo.io, talking about our propensity to include too many libraries when starting up a JavaScript project:
Flashbacks to the 15,683 files This is why I'm writing that quick series on Templating without Transpilation with VueJS. I'm not saying it's The Right Way to create a client-side stack, but it's a thought experiment worth thinking through -- like Reich's, above, or even Dan Abramov's famous-ish "You Might Not Need Redux. Labels: coding, javascript, style posted by ruffin at 4/23/2018 08:33:00 PM |
||||||||||||||||
| Wednesday, March 28, 2018 | ||||||||||||||||
|
From martinfowler.com on "Command Query Responsibility Segregation", or CQRS:
As this occurs we begin to see multiple representations of information. When users interact with the information they use various presentations of this information, each of which is a different representation... This structure of multiple layers of representation can get quite complicated, but when people do this they still resolve it down to a single conceptual representation which acts as a conceptual integration point between all the presentations. The change that CQRS introduces is to split that conceptual model into separate models for update and display, which it refers to as Command and Query respectively following the vocabulary of CommandQuerySeparation. The rationale is that for many problems, particularly in more complicated domains, having the same conceptual model for commands and queries leads to a more complex model that does neither well. I saw this acronym for the first time today in a SO question about Azure Service Fabric, and my HOT TAKE!!11! was, "Who in the world doesn't do this?" There are two main data transformations that happen in essentially all of my controller code. For GETs, I'm usually flattening a "database is truth" model into a data payload, stripped of stuff like, "LastModifiedBy" (or anything not needed by the client), but also of complex relationships with child objects. That is, when Entity Framework (or any POCO-returning library) gives me, say, an address' stateOrProvince as an entity, I usually flatten that to a The second is when I return changes to these DTOs. There, the PUT (or PATCH) command often isn't strictly RESTful either [using the database as The Source of Truth]. If I'm returning the ever-proverbial Contact with three Addresses, I don't typically call an Addresses endpoint with a PUT thrice, and then follow up with another PUT to Contacts. I'll send up a DTO that's essentially There is nothing that, in my experience, causes performance bottlenecks as quickly as folks blindly falling back on performing Commands (actions that "Change the state of a system but do not return a value") via fully hydrated ORM objects. Oh, the humanity. Treating your PUTs and PATCHes as separate models from your GETs (or at least separate models from those in your database schema) allows you to spare yourself such madness. posted by ruffin at 3/28/2018 01:51:00 PM |
||||||||||||||||
| Monday, February 19, 2018 | ||||||||||||||||
|
If your architect hasn't written a tutorial -- not a cursory howto, but a tutorial -- you don't have an architect. What does a tutorial look like? The canonical example for C# web apps, though now a bit long in the tooth, is NerdDinner:
There's not only a nicely written walkthrough, but documented code and a live, running example. If your architect hasn't taken the time to articulate their vision thoroughly, in plain, if expert-specific, [language of your locale], there's not much hope for your coders. Your codebase will necessarily be an unmaintainable cyborg (a topic I'm [not] surprised to find I've been ranting about since 2002). The best job security is none. You've set your stage so well any competent programmer could come in and take over, getting up to speed incredibly quickly. Those coders who work to ensure they're the most easily replaced are absolutely irreplaceable. Labels: architecture, coding, cyborg, style posted by ruffin at 2/19/2018 10:02:00 AM |
||||||||||||||||
| Monday, March 13, 2017 | ||||||||||||||||
|
Jay Bazuzi was talking about how to make the work of distributed teams run more smoothly, and there was a term he used that I thought deserved a little googling...
As it turns out, Conway's Law is pretty interesting. Here's some more, from Demystifying Conway's Law on ThoughtWorks:
The real take-home comes just a little later, though, I think:
That the work of distributed teams -- or, if you ask me, any team -- can be coordinated more easily when you take the time to clearly define the interface surrounding their work seems like a truism. Though I'd never given the converse enough thought. If you have a widely distributed [read: "entirely remote"] team that doesn't tend to communicate, having a monolithic codebase, especially one without documentation, can absolutely hamstring development. Or, at best, it means that your team will tend to ignore what exists and replace with whatever seems best. If you start eating away at the monolith in good, interfaced, discrete chunks, however, that's probably about as good as means of erasing it as you can get. Regardless, I think the lesson here is that the downfalls of poorly documented, monolithicly designed codebases are compounded in easy to identify and productivity unfriendly ways in distributed/remote work environments. Say that three times quickly. Even better: Remote environments require well factored code. Labels: coding, monolithic, productivity, remote, style posted by ruffin at 3/13/2017 08:30:00 AM |
||||||||||||||||
| Thursday, February 09, 2017 | ||||||||||||||||
|
From silvrback.com (via Michael Tsai):
Yes. But with their example -- granting it's a simplest case, "staged house" example -- no. No. Heavens no. While they admit it a bit...
Yes. It doesn't just border, it's over the line.
posted by ruffin at 2/09/2017 09:30:00 AM |
||||||||||||||||
| Monday, January 30, 2017 | ||||||||||||||||
|
From The Single Page Interface Manifesto:
That's an interesting group of languages. I wonder if it isn't fairly representative of at least where operative internet architectures were being developed when it was written. There seems to be an exceptionally skilled contingent of programmers in Eastern Europe. I wonder what they're doing right, and how hard it'd be to do elsewhere. posted by ruffin at 1/30/2017 10:29:00 PM |
||||||||||||||||
| Saturday, January 28, 2017 | ||||||||||||||||
|
If there's one often-overlooked feature in Windows that I really enjoy using, it's the "Cascade all windows" feature for the taskbar. I've been told -- unprovoked, so you know it's bad -- that I tend to have a lot of windows open when I'm working. It's true. I do. And when it's time to clean them all up, it's nice not to have to declare "windows management bankruptcy" and close everything I have open in an app before closing it out. To dodge this, you can hold down shift as you right-click a taskbar icon, and select the option from this menu:
Well, often you can do this and quickly go through whatever the app has open. What Chrome does is less than particularly helpful. It's hard to see there, but you can't read any window titles other than the very first one. You can click the image to make it full-sized. What's displayed sort of gives you an idea of how much you're going to have to sift though, but it's otherwise not insanely helpful. Here it is, up close.
I can tell my order has shipped in the front window, and how many tabs I have open in the other five, but that's it. Done. Look at what Edge does.
It's a little hard to see the details in the picture, but you can get a feeling of how absolutely beautiful (and by "beautiful", like any good engineer, I mean "practical" and "useful") that is. I can see every window, every tab, every title. Now I can quickly hit the X at the top right to close any window I'm done using & that needs to go away. Here's what Edge shows when "cascaded", zoomed in.
Being a good residentEdge gets Windows. You might say you're not surprised, but what is surprising is how badly Chrome flubs it. I mean, I understand the, "They even use Material Design on iOS, man!" argument, but I'm not buying that doing so requires that you be a bad Windows resident. Edge looks distinctly different from Internet Explorer, for instance. You've got plenty of leeway before you lose your design language, so to speak. And even though Apple, for instance, completely ignored all the good Windows resident requests with iTunes and WinSafari, two wrongs don't make a right. In short, it's not that hard to push the titles up into all of that dead white space in Chrome.
Why not use that for displaying real information, even if there wasn't the option to cascade windows? And since there is, well, let's just say that it's a horribly efficient, beautiful thing when the title bar/browser tabs are done right. posted by ruffin at 1/28/2017 01:51:00 PM |
||||||||||||||||
| Tuesday, January 24, 2017 | ||||||||||||||||
|
And now, for a little from the Flux intro docs:
Chicken dinner. Labels: client, coding, javascript, style posted by ruffin at 1/24/2017 10:23:00 PM |
||||||||||||||||
| Wednesday, January 04, 2017 | ||||||||||||||||
|
Today, I ran across a clickbaitily titled post called Just Say No to More End-to-End Tests posted at the Google Testing Blog, written back on April 22, 2015, detailing a fictional end-to-end (e2e) testing run. The scenario was very clearly fictionalized, but you can forgive most of it, as they're simply trying to illustrate a few points. Here's their "analysis" of the test, which apparently took over a week to complete and had some serious errors with the testing apparatus as well.
The author uses this cluster of an e2e test to argue for a preponderance of unit and integration tests...
That's a lot of info to digest. Here's the problem: "Simulates a Real User" isn't a single point. Their chart really isn't a scorecard, though that's how it's presented. My quick list of critiques:
Look, more typical situations in my experience are that you either have lip-service unit tests [only] or that you have no testing at all. Guess what's most valuable if you have to pull teeth to convince management that testing is important? In my experience, it's an "end to end" test. You'll get the most return on your testing resource dollar with smoke tests. I do like to call it a smoke test, and I've had pretty good results using Selenium to automate a browser using C#. Which browser? Well, you get your biggest bang for the buck by just using one. It'd be great to test in IE, Firefox, Edge, Chrome, and even macOS & iOS Safari, but each time is a diminishing return. The first test in whatever browser is going to catch 75% of what's wrong. I recommend using either 1.) The lowest common denominator for browser functionality, usually IE, or 2.) Whatever's the easiest to get to behave for your tests. Timing can be a pain in Selenium. Recently, I've used Selenium's Chrome web driver. That's dangerous. Chrome seems the most fault tolerant of the browsers, and on a developer's phat box, you can add slow downs to browser incompatibilities as problems that are often hard to notice. But one browser, going through an automated master set of user stories, will quickly ensure that the 80% of your website that's your real bread and butter works and wasn't screwed up by whatever whizbang gizmo your latest release just pushed out the door. If there is an error, sure, it can be hard to immediately identify the exact cause, which the Testing Blog seems to think is the end of the world. And perhaps a unit test to cover each error you do discover and track down will be useful. Do that. But, again, unless you're doing TDD, to ask developers to write useful unit tests ahead of time almost never covers what your users are actually going to do and doesn't prevent bugs your own developers and QA are going to catch anyway. To get useful unit tests, you're going to have to spend even more time getting developers to code review others' unit tests, and you barely had time to green light unit tests to begin with. (How do I know that? If you had plenty of time, you'd be using TDD.) And if you've gotten so far down the line that you can't tell if an error is coming from the front or back end, as in the Testing Blog's worst-case scenario, well, you have worse problems. My suggestion if you're losing days looking for bugs your e2e tests turn up, and more days with your test lab going down? Forget the users; your development process is broken. It's time to start arguing for TDD. Update: Interesting to look at the slide linked in the quote, above:
And the notes address what I'm saying exactly (and argue against it):
Interesting. I'm going to guess Google's coders do a much better job writing tests. If you want to convince me, talk more about how tests are written, and less about how they're better than automated UI testing if you have no testing now. But wow, look at some later slides:
Comments to that slide:
Not great. I've heard what's important when coding is to know which bugs to ship, but which bugs in tests to ignore? What are we doing? Later on...
EXACTLY. I think the Testing Blog grossing oversimplified the take-home from this fellow's presentation. I'll job bombarding pixels now. posted by ruffin at 1/04/2017 01:23:00 PM |
||||||||||||||||
| Monday, December 19, 2016 | ||||||||||||||||
|
Have you tried using Facebook's
Fifteen-thousand, six-hundred, eighty three files for over sixty megs of space, and I haven't added a single line of code. Wow, just the readme of how to use what you just installed is 57 kilobytes of light reading. Shawn Wildermuth talked to a similar issue, here Angular, but with an eye on any large framework, on Yet Another Podcast with Jesse Liberty in August. 8:18:
I'm pretty much in the same camp, as you likely know. I think you'd have to talk me out of using a "logic-less" templating system like moustache or handlebars first. I like the concept of React's virtual DOM, but when diffing DOM and updating selectively is a cheaper operation than your standard update paradigm, that's a pretty hefty code smell. When you have something like Remember folks: If you're performing cascading calculations on the client, that's an architecture smell. Get that logic where it belongs, and don't use frameworks that encourage you to place it somewhere unwise. Quick update 20161231: Check out how long it takes to expand and copy over a zipped copy of the unmodified Labels: coding, javascript, libs, react, style posted by ruffin at 12/19/2016 06:35:00 PM |
||||||||||||||||
| Wednesday, November 30, 2016 | ||||||||||||||||
|
From Tips for Writing Portable Node.js Code:
This is a problem when serving files by name with express' So what if you want to use Express to serve files from the filesystem on, I don't know, Ubuntu on linode [which uses ext4]? And what if you want folks to be able to access your privacy policy at both http://rufwork.com/Privacy/ and http://rufwork.com/privacy/? Even worse, what if you told your app reviewer to try http://rufwork.com/privacy/ and that meant they had to reject your app submission now that you've changed servers? /facepalm From MarkUpDown - Review Results:
(>แ) I've never liked it when I've typed in a URL by hand and got a 404 because I had one or two letters in the wrong case. I mean, it makes sense that case sensitive file systems are easier to maintain. It's just an end-use-case pain when you're serving files. But URL case in Edge is broken too... ๐๐ฑAnd insult to injury? Microsoft Edge (Internet Explorer's replacement in Win10) "remembers" case when you retype a URL! What, wait? So I can't navigate to the "correctly cased" URL with Edge even if I want to -- and I wonder if I get the same reviewer(s) if this'll happen to them too. (>แ) How to fix itHow do you fix case sensitivity for express so that it's never a problem with ext4? Well, you could make everything in your filesystem lowercase, and then just always run From expressjs.com:
Still have to set the filesystem to a single case throughout, and then if you want to use mixed case in your URLs to make them easier to remember or what-have-you, you're creating a good deal of extra work for your server every time mixed case is used. How bad is it to make your web server take a URL, not find it, then search the filesystem again for a lower cased version? It might be smarter/less work just to lowercase the string every time and ensure your filesystem is in sync. It has to be cheaper to lowercase the url every time than to hit So I guess it looks like I get to go through and change the case of my website's files and folders to a single case. Right? Isn't that The Right Thing to do to approximate case insensitivity? Is it ever better for the end user to have a case sensitive http server? I don't think so. Seems unnecessarily processor churny and hacky to lower case the earth, but man, I hate case sensitivity for URLs. That fishing metaphor that tells you I'm about to comprise my best intentions...In any event, for now, I've decided to embarrassingly give the server a fish, I'm afraid.
That's probably worth a Unicode facepalm too. I really enjoy using linode, though my needs are so small I might drop down to Digital Ocean's $5 a month plan if it's just as easy to administer. It's great having your own "box" on the net. So much more powerful than shared hosting. Feel like I was about a decade behind with hosts, but, boy, I'm caught up now. Wonder how long before I start using .NET Core on it... posted by ruffin at 11/30/2016 12:47:00 PM |
||||||||||||||||
| Tuesday, November 15, 2016 | ||||||||||||||||
|
There's a repeated joke in the Rockford Files that everyone in or that has been in jail was innocent; just ask them. (Of course, we're supposed to assume Jim really is innocent, but I've leave the meta alone for now.) Ever heard something similar with programmers? Have you ever met a programmer who won't tell you they're a superstar? Coders' self-proclaimed brilliance is like ex-cons' proclamations of innocence. Seriously, who doesn't think they're above average? The sea of programmers thinks itself an extended version of Lake Wobegon. A more interesting discussion would be to ask yourself why every coder thinks that and who is encouraging it, but I'm leaving that alone for now too. ;^) posted by ruffin at 11/15/2016 09:14:00 AM |
||||||||||||||||
| Thursday, October 13, 2016 | ||||||||||||||||
|
From daringfireball.net:
Exactly right. I've had it do the same thing when I ask Siri to give me directions home, usually because I want to know if there's enough traffic to go an alternate route, and I get the same, "Who are you?!" complaint. But if I open Maps, "Home" is usually the first location listed. QA sucks at Apple. I'm no longer politely questioning it. Spend ten million (he said figuratively) and get the best QA staff in the business, and make sure there's no silo making QAing app interactions an issue. If Maps borks like this, the QA team "for Maps" has to be able to hold Siri and Contacts (or whatever else) accountable. No software ships until this blocking bug is fixed. Good QA will think of and try these sorts of pretty obvious, yet creative, use (not edge, simply "use") cases before you ship. Pitiful. Seriously pitiful. posted by ruffin at 10/13/2016 02:38:00 PM |
||||||||||||||||
| Friday, September 09, 2016 | ||||||||||||||||
|
Oh, Pivots in UWP, you so crazy. You may have heard that I'm writing a Markdown editor, MarkUpDown. It can have several files open at once, of course, and I'm using a UWP Pivot control to handle navigation. As I got closer to releasing, it hit me that Ctrl-W, though common, isn't the most discoverable way to close those PivotItems. And now that I'm maintaining state between starts, so that whatever tabs you have open when you close the app are back on restart, closing each file "on purpose" is a lot more important than when they all closed on each restart. That is, it looks like I need a UI for closeable tabs. Not as easily said as done. You can customize the In that UserControl, I put a I replaced the
That's fun, isn't it?
That looks okay, but there are still two problems.
Okay, three problems -- I really should change the icon to a greyed-out version when the Accessing a property in custom XAML from CI found the answer to the first pretty easily: You have to use a Dependency Property, of course!
But wait! There's more!
I feel like the Knights of the Round Table after they've considered whether to go to Camelot. Okay, nevermind. 'Tis a silly place. I won't make these new headers XAML-friendly for "version mvp". We're going to set the Label somewhere outside of XAML. Moving on to #2... Removing a
|
||||||||||||||||
|
| ||||||||||||||||
|
|
All posts can be accessed here: Just the last year o' posts: |
|||||||||||||||||||||
|
||||||||||||||||||||||
|
|
|
|