Skip to content

Instantly share code, notes, and snippets.

public static class PasswordHelpers
{
private static bool GetPasswordInitialized(DependencyObject obj)
{
return (bool)obj.GetValue(PasswordInitializedProperty);
}
private static void SetPasswordInitialized(DependencyObject obj, bool value)
{
obj.SetValue(PasswordInitializedProperty, value);
}
public static class ReactiveExtensionsExtensions
{
public static async Task SubscribeAsync<T>(this IObservable<T> observable, Action<T> onNext, CancellationToken? cancellationToken = null)
{
CancellationToken token = cancellationToken ?? CancellationToken.None;
var cts = new TaskCompletionSource<bool>();
using(token.Register(() => cts.SetCanceled()))
{
observable.Subscribe(onNext, ex => cts.SetException(ex), () => cts.SetResult(true), token);
await cts.Task;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
namespace ConfigManager
{
public class ConfigManager : IDisposable
{
@canton7
canton7 / AtomicFileStream.cs
Last active February 23, 2018 23:03
An attempt to allowing atomic file writes on windows
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace FilesystemUtils
{
public class AtomicFileStream : FileStream
{
private const int DefaultBufferSize = 4096;
private const string DefaultTempFileSuffix = ".tmp";
public class GlobalKeyboardHook : IDisposable
{
private delegate IntPtr LowLevelKeyboardProc(int nCode, int wParam, IntPtr lParam);
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private const int WM_KEYUP = 0x0101;
private const int VK_SHIFT = 0x10;
private const int VK_CONTROL = 0x11;
public class Foo : IEquatable<Foo>
{
public int Bar { get; set; }
public int Baz { get; set; }
public override bool Equals(object obj)
{
return this.Equals(obj as Foo);
}
using System;
using System.Windows.Data;
using System.Windows.Markup;
namespace LocalizationDemo.Localization
{
public class LocExtension : MarkupExtension
{
/// <summary>
/// Gets or sets the key to use to look up the appropriate value to display.
@canton7
canton7 / Setup.iss
Last active February 1, 2023 21:32
Installing .NET Framework 4.6.1 with Inno Setup
#define DotNetRuntimeExe "NDP461-KB3102436-x86-x64-AllOS-ENU.exe"
[CustomMessages]
InstallingDotNetFramework=Installing .NET Framework. This might take a few minutes...
DotNetFrameworkFailedToLaunch=Failed to launch .NET Framework Installer with error "%1". Please fix the error then run this installer again.
DotNetFrameworkFailed1602=.NET Framework installation was cancelled. This installation can continue, but be aware that this application may not run unless the .NET Framework installation is completed successfully.
DotNetFrameworkFailed1603=A fatal error occurred while installing the .NET Framework. Please fix the error, then run the installer again.
DotNetFrameworkFailed5100=Your computer does not meet the requirements of the .NET Framework. Please consult the documentation.
DotNetFrameworkFailedOther=The .NET Framework installer exited with an unexpected status code "%1". Please review any other messages shown by the installer to determine whether the installation completed successfully, and abort this
  1. Pootle: Self-hosted. Slightly annoying to get set up, seems to work thereafter. Uses a command-line tool to upload/download translations. Didn't evaluate too much.
  2. Weblate: Self-hosted offshoot of Pootle. Very annoying to set up. Seems to have a nicer interface but wants to integrate directly with your VCS - no command-line tooling. The VCS integration adds a lot of complexity. Didn't evaluate too much.
  3. Zanata: Self-hosted, easy to set up. Poor access controls - geared towards open collaboration. Command-line tool. Nice interface.
  4. POEditor: Paid hosting, with a free tier. No command-line tool as far as I can see.
  5. CrowdIn: Paid hosting, free for open source. Very nice interface, good API and command-line tooling. Good GitHub integration. This is the one we went for.
/// <summary>
/// Extensions on TreeViews allowing users to bind to the SelectedItem property
/// </summary>
/// <remarks>
/// The trick used to detect when the binding has occurred means that there are some cases it doesn't handle - but I don't
/// recall what.
/// </remarks>
public static class TreeViewExtensions
{
private static readonly object initialBindingTarget = new object();