<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Get Your Bits Together]]></title><description><![CDATA[Documenting lessons learned in programming.]]></description><link>https://getyourbitstogether.com/</link><image><url>https://getyourbitstogether.com/favicon.png</url><title>Get Your Bits Together</title><link>https://getyourbitstogether.com/</link></image><generator>Ghost 5.13</generator><lastBuildDate>Sun, 12 Apr 2026 15:43:48 GMT</lastBuildDate><atom:link href="https://getyourbitstogether.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Quickly Create .gitignore File]]></title><description><![CDATA[Create a pre-populated .gitignore file via the dotnet CLI.]]></description><link>https://getyourbitstogether.com/adding-a-new-gitignore-file/</link><guid isPermaLink="false">6412912b3a609603e410e959</guid><dc:creator><![CDATA[Brandon Baker]]></dc:creator><pubDate>Thu, 16 Mar 2023 03:51:22 GMT</pubDate><content:encoded><![CDATA[<p>If you want to quickly create a <code>.gitignore</code> file that has dotnet specifics pre-populated, know that you can create a gitignore file via the dotnet command line. In a command prompt, just navigate to the directory where you&apos;d like the gitignore file to be created and use this command:</p><pre><code class="language-shell">dotnet new gitignore</code></pre>]]></content:encoded></item><item><title><![CDATA[Flurl multipart/form-data Unexpected End of Stream]]></title><description><![CDATA[This is a solution to an IOException "Unexpected end of Stream" when using Flurl to post multipart/form-data.]]></description><link>https://getyourbitstogether.com/flurl-multi-part-form/</link><guid isPermaLink="false">637681913a609603e410e895</guid><category><![CDATA[csharp]]></category><category><![CDATA[flurl]]></category><category><![CDATA[aspnetcore]]></category><dc:creator><![CDATA[Brandon Baker]]></dc:creator><pubDate>Fri, 18 Nov 2022 00:00:46 GMT</pubDate><content:encoded><![CDATA[<p>I recently was attempting to upload multipart/form-data using <a href="https://flurl.dev">Flurl</a> and ASPNET Core server was throwing this exception: &quot;System.IO.IOException: Unexpected end of Stream, the content may have already been read by another component.&quot;.</p><h2 id="tldr">TLDR</h2><p>The <u>root cause</u> of this error is that the <strong>boundary value was wrapped in double quotes</strong> in the media type header but was not wrapped in quotes in the request body. The <u>solution</u> was just to trim the double quotes from the boundary value.</p><h2 id="deeper-dive">Deeper Dive</h2><p>Here&apos;s the content-type header value from the http request. Notice how the GUID is wrapped in double quotes.</p><figure class="kg-card kg-code-card"><pre><code class="language-http">multipart/form-data; boundary=\&quot;8fee35ce-e3f2-4589-9992-d4871575effa\&quot;</code></pre><figcaption>The HTTP Request&apos;s Content-Type Header Value</figcaption></figure><p>Here&apos;s the gist of the request body (binary data omitted). Notice how the same GUIDs lack the double quotes.</p><figure class="kg-card kg-code-card"><pre><code>--8fee35ce-e3f2-4589-9992-d4871575effa
Content-Type: application/octet-stream
Content-Disposition: form-data; name=file; filename=foo.jpg; filename*=utf-8&apos;&apos;foo.jpg

BINARY DATA
--8fee35ce-e3f2-4589-9992-d4871575effa--</code></pre><figcaption>The HTTP Request Body</figcaption></figure><p>I was using <code>Microsoft.AspNetCore.WebUtilities.MultipartReader</code> to read the http request body. Like so:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">var reader = new MultipartReader(mediaTypeHeader.Boundary.Value, request.Body);</code></pre><figcaption>The MultipartReader declaration</figcaption></figure><p> The exception was being thrown on this line directly below:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">var section = await reader.ReadNextSectionAsync(cancellationToken);</code></pre><figcaption>The line throwing the IOException</figcaption></figure><p>The solution was to trim the double quotes from the boundary:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">var reader = new MultipartReader(mediaTypeHeader.Boundary.Value.Trim(&apos;&quot;&apos;), request.Body);</code></pre><figcaption>The fixed MultipartReader declaration</figcaption></figure><p></p>]]></content:encoded></item><item><title><![CDATA[Get LiteDb Collection From CLR Type]]></title><description><![CDATA[This post shows how to resolve a `ILiteCollection<BsonDocument>` from LiteDb using a `System.Type` instance.]]></description><link>https://getyourbitstogether.com/get-litedb-collection-from-clr-type/</link><guid isPermaLink="false">62da01136f9a3d558b77a9f5</guid><category><![CDATA[csharp]]></category><category><![CDATA[litedb]]></category><dc:creator><![CDATA[Brandon Baker]]></dc:creator><pubDate>Fri, 22 Jul 2022 01:55:42 GMT</pubDate><content:encoded><![CDATA[<p>If you use <a href="https://github.com/mbdavid/LiteDB">LiteDB</a>, you might need to resolve a <code>ILiteCollection&lt;BsonDocument&gt;</code> from a .NET type. Here&apos;s how you can do that.</p><pre><code class="language-csharp">public static class LiteDatabaseExtensions
{
    public static ILiteCollection&lt;BsonDocument&gt; GetCollectionByType(this ILiteDatabase database, Type type)
    {
        if (database == null)
        {
            throw new ArgumentNullException(nameof(database));
        }

        if (type == null)
        {
            throw new ArgumentNullException(nameof(type));
        }

        // We can use the database&apos;s built in BsonMapper to get the default collection name for the type.
        // This technique only works for collections that were resolved without custom names.
        // EX: var collection = database.GetCollection&lt;T&gt;();
        var collectionName = database.Mapper.ResolveCollectionName(type);
        var collection = database.GetCollection(collectionName);
        return collection;
    }
}</code></pre>]]></content:encoded></item><item><title><![CDATA[Fixing SEC_ERROR_INADEQUATE_KEY_USAGE in Firefox]]></title><description><![CDATA[This post explains how to fix the SEC_ERROR_INADEQUATE_KEY_USAGE error that sometimes occurs when you visit a secure url in Firefox.]]></description><link>https://getyourbitstogether.com/fixing-sec_error_inadequate_key_usage/</link><guid isPermaLink="false">61c036f36f9a3d558b77a9b2</guid><dc:creator><![CDATA[Brandon Baker]]></dc:creator><pubDate>Mon, 20 Dec 2021 08:06:11 GMT</pubDate><content:encoded><![CDATA[<h2 id="the-problem">The Problem</h2><p>When loading a secure url (https) in Firefox, you see &quot;Secure Connection Failed&quot;, &quot;Error code: SEC_ERROR_INADEQUATE_KEY_USAGE&quot;.</p><h2 id="the-solution">The Solution</h2><ol><li>Go to <code>about:profiles</code> in Firefox. Do this by entering &quot;about:profiles&quot; in the address bar like a URL.</li><li>Locate the profile that is currently in use. This will be the profile that has no Remove button.</li><li>Click <strong>Open Folder</strong> in <strong>Root Directory</strong>.</li><li>Delete the <em>cert9.db</em> and <em>cert_override.txt</em> files. You may need to close Firefox to delete these files.</li><li>Try problematic url again. The problem should be resolved.</li></ol>]]></content:encoded></item><item><title><![CDATA[Swap Two Variables Without Temporary Variable]]></title><description><![CDATA[This example shows how to swap two variables without using a temporary variable.]]></description><link>https://getyourbitstogether.com/swap-two-variables-without-temporary-variable/</link><guid isPermaLink="false">60ab11c26f9a3d558b77a98b</guid><category><![CDATA[csharp]]></category><category><![CDATA[beginner]]></category><dc:creator><![CDATA[Brandon Baker]]></dc:creator><pubDate>Mon, 24 May 2021 02:46:45 GMT</pubDate><content:encoded><![CDATA[<p>It turns out there&apos;s finally a simple and efficient way to swap two variables without using a temporary variable, thanks to <a href="https://stackoverflow.com/questions/804706/swap-two-variables-without-using-a-temporary-variable">this StackOverflow post</a>. As of C# 7.0, you can use tuples like in the example below.</p><pre><code class="language-csharp">int a = 1;
int b = 0;
(a, b) = (b, a);</code></pre><p>Evidently it&apos;s just as efficient as using a temporary variable as well. The generated IL (machine code) is <a href="https://www.reddit.com/r/ProgrammerTIL/comments/8ssiqb/cyou_can_swap_values_of_two_variable_with_the_new/e12301f/">exactly the same as if you used a temporary variable</a>.</p>]]></content:encoded></item><item><title><![CDATA[Change WPF Button Visibility Based On Command.CanExecute]]></title><description><![CDATA[This post shows how to set WPF button's visibility based on whether or not its bound command can execute.]]></description><link>https://getyourbitstogether.com/change-wpf-button-visibility-based-on-command-canexecute/</link><guid isPermaLink="false">606157e96f9a3d558b77a941</guid><category><![CDATA[csharp]]></category><category><![CDATA[wpf]]></category><dc:creator><![CDATA[Brandon Baker]]></dc:creator><pubDate>Mon, 29 Mar 2021 04:38:22 GMT</pubDate><content:encoded><![CDATA[<p>Here&apos;s a quick way to change to the visibility of your WPF button based on its command status.</p><p>In the example below, there&apos;s a <code>Button</code> that is bound to a property named <code>Save</code> on view model. <code>Save</code> is an <code>ICommand</code> and the behavior of the button is to enable or disable itself based on whether or not the <code>ICommand.CanExecute</code> returns true or false. This sets the button&apos;s <code>IsEnabled</code> property, and thus we can set a binding on the button&apos;s <code>Visibility</code> property that changes when the button is enabled or disabled. Note that in the binding, a <code>BooleanToVisibilityConverter</code> is used to convert a boolean to a corresponding <code>Visibility</code> enum value.</p><pre><code class="language-xaml">&lt;Button
    Command=&quot;{Binding Path=Save}&quot;
    Content=&quot;Save&quot;
    Visibility=&quot;{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsEnabled, Converter={StaticResource BooleanToVisibilityConverter}}&quot; /&gt;</code></pre>]]></content:encoded></item><item><title><![CDATA[WPF ListBox Selection via CheckBox]]></title><description><![CDATA[Here's an easy way to control your ListBox's selection by using a CheckBox in each item.]]></description><link>https://getyourbitstogether.com/wpf-listbox-selection-with-checkbox/</link><guid isPermaLink="false">604068c66f9a3d558b77a8cb</guid><category><![CDATA[wpf]]></category><category><![CDATA[csharp]]></category><dc:creator><![CDATA[Brandon Baker]]></dc:creator><pubDate>Thu, 04 Mar 2021 05:20:45 GMT</pubDate><content:encoded><![CDATA[<p>Here&apos;s a simple solution to add check boxes to a ListBox (or other similar controls) in WPF. This solution will keep the selection of the check box in sync with the list box&apos;s <code>SelectedItems</code>.</p><h2 id="tldr">TLDR</h2><p>The TLDR is that you should add a <code>CheckBox</code> control to your <code>DataTemplate</code> and then bind the box&apos;s <code>IsChecked</code> property to the <code>ListBoxItem.IsSelected</code> property, using a relative source binding.</p><h2 id="mainwindow-xaml">MainWindow.xaml</h2><p>In this file, we&apos;ve got a <code>ListBox</code> that is bound to an <code>Items</code> property on the <code>Window</code>. The ListBox&apos;s <code>SelectionMode</code> property has been set to <code>Multiple</code> to allow multiple items to be selected at a time. Additionally, the <code>ListBox.ItemTemplate</code> has been set to a custom <code>DataTemplate</code> which contains our <code>CheckBox</code>. The <code>IsChecked</code> property is bound to the <code>IsSelected</code> property of the <code>ListBoxItem</code>.</p><p><code>ListBox</code> controls automatically create a <code>ListBoxItem</code> for every item provided in the <code>ListBox.ItemsSource</code>. Every <code>ListBoxItem.IsSelected</code> is kept in sync with the containing <code>ListBox</code> control and that <code>IsSelected</code> property can be modified to change what&apos;s selected within the <code>ListBox</code>.</p><p>By using a <code>RelativeSource</code> binding on our <code>IsChecked</code> property, we tell the <code>CheckBox</code> to crawl up the tree until the containing <code>ListBoxItem</code> is located (via the <code>AncestorType</code>). Once the item is located, we simply bind to the item&apos;s <code>IsSelected</code> property, effectively synchronizing our <code>CheckBox.IsChecked</code> state to the <code>ListBoxItem.IsSelected</code> state. </p><pre><code class="language-xaml">&lt;Window x:Class=&quot;MultiSelectionSpike.MainWindow&quot;
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
        xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
        xmlns:local=&quot;clr-namespace:MultiSelectionSpike&quot;
        d:DataContext=&quot;{d:DesignInstance local:MainWindow}&quot;
        mc:Ignorable=&quot;d&quot;
        Title=&quot;MainWindow&quot; Height=&quot;450&quot; Width=&quot;800&quot;&gt;
    &lt;ListBox ItemsSource=&quot;{Binding Path=Items}&quot; SelectionMode=&quot;Multiple&quot;&gt;
        &lt;ListBox.ItemTemplate&gt;
            &lt;DataTemplate&gt;
                &lt;DockPanel&gt;
                    &lt;CheckBox IsChecked=&quot;{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}&quot; DockPanel.Dock=&quot;Left&quot; /&gt;
                    &lt;TextBlock Text=&quot;{Binding}&quot; /&gt;
                &lt;/DockPanel&gt;
            &lt;/DataTemplate&gt;
        &lt;/ListBox.ItemTemplate&gt;
    &lt;/ListBox&gt;
&lt;/Window&gt;
</code></pre><h2 id="mainwindow-xaml-cs">MainWindow.xaml.cs</h2><p>A few points to note about this class. First, it defines the <code>Items</code> property that is used by the <code>ItemsSource</code> in our xaml. Next, it initializes a new collection with some sample items in it. Finally, it sets <code>MainWindow</code>&apos;s <code>DataContext</code> to itself, enabling the <code>ItemsSource</code> binding to work correctly.</p><pre><code class="language-csharp">using System.Collections.ObjectModel;

namespace MultiSelectionSpike
{
    /// &lt;summary&gt;
    ///     Interaction logic for MainWindow.xaml
    /// &lt;/summary&gt;
    public partial class MainWindow
    {
        public MainWindow()
        {
            Items = new ObservableCollection&lt;string&gt; {&quot;First&quot;, &quot;Second&quot;, &quot;Third&quot;};
            InitializeComponent();
            DataContext = this;
        }

        public ObservableCollection&lt;string&gt; Items { get; }
    }
}
</code></pre>]]></content:encoded></item><item><title><![CDATA[Binding To Attached Properties]]></title><description><![CDATA[This quick post shows how to bind to attached properties in xaml and code-behind.]]></description><link>https://getyourbitstogether.com/binding-to-attached-properties/</link><guid isPermaLink="false">5fe912a66f9a3d558b77a828</guid><category><![CDATA[wpf]]></category><category><![CDATA[csharp]]></category><dc:creator><![CDATA[Brandon Baker]]></dc:creator><pubDate>Sun, 27 Dec 2020 23:29:29 GMT</pubDate><content:encoded><![CDATA[<p>This post demonstrates a couple of different ways to bind to attached properties in WPF.</p><p>First, here&apos;s the code for the attached property that will be used in the demonstrations below. In this code, an attached property named <code>Foo</code> is defined within the <code>Demonstration</code> class. The attached property can be attached to any <code>DependencyObject</code>.</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">public static class Demonstration
{
    public static readonly DependencyProperty FooProperty = 
        DependencyProperty.RegisterAttached(&quot;Foo&quot;,
        typeof(string), typeof(Demonstration),
        new PropertyMetadata(default(string)));

    public static void SetFoo(DependencyObject element, string value)
    {
        element.SetValue(FooProperty, value);
    }

    public static string GetFoo(DependencyObject element)
    {
        return (string)element.GetValue(FooProperty);
    }
}</code></pre><figcaption>The Foo attached property</figcaption></figure><p>The example&apos;s DataContext has been set to <code>this</code> in the constructor.</p><pre><code class="language-csharp">DataContext = this;</code></pre><h2 id="in-xaml">In XAML</h2><p>The code in this example will bind the <code>Foo</code> attached property to the <code>Title</code> property in XAML. Note that the namespace <code>local</code> is set to the <code>DemoApp</code> namespace. That&apos;s because the <code>Demonstration</code> class that defines the attached property is located there. In this case, no binding source has been provided, so the <code>DataContext</code> will be assumed as the binding source.</p><pre><code class="language-xaml">xmlns:local=&quot;clr-namespace:DemoApp&quot;
Title=&quot;{Binding Path=(local:Demonstration.Foo)}&quot;</code></pre><h2 id="in-code-behind">In Code-Behind</h2><p>Here&apos;s how to do the same thing in code-behind. This specific example assumes that <code>this</code> is a <code>System.Windows.Controls.Page</code> instance. Similarly, no source has been set on the <code>binding</code>, so the <code>DataContext</code> will act as the source.</p><pre><code class="language-csharp">var binding = new Binding
{
    Path = new PropertyPath(&quot;(0)&quot;, new object[] { Demonstration.FooProperty })
};
BindingOperations.SetBinding(this, Page.TitleProperty, binding);</code></pre>]]></content:encoded></item><item><title><![CDATA[Polymorphic Serialization in System.Text.Json]]></title><description><![CDATA[This post offers a solution for polymorphic json serialization using System.Text.Json.]]></description><link>https://getyourbitstogether.com/polymorphic-serialization-in-system-text-json/</link><guid isPermaLink="false">5fd55f056f9a3d558b77a75f</guid><category><![CDATA[csharp]]></category><dc:creator><![CDATA[Brandon Baker]]></dc:creator><pubDate>Sun, 13 Dec 2020 02:57:14 GMT</pubDate><content:encoded><![CDATA[<h2 id="problem">Problem</h2><p>Sometimes when you&apos;re serializing a C# class to JSON, you want to include polymorphic properties in the JSON output. If you&apos;re using System.Text.Json (version 4.0.1.0 or lower) to do the serialization, this won&apos;t happen automatically. Consider the following code below for an example.</p><pre><code class="language-csharp">public class Chart
{
    public ChartOptions Options { get; set; }
}

public abstract class ChartOptions
{
    public bool ShowLegend { get; set; }
}

public class LineChartOptions : ChartOptions
{
    public IEnumerable&lt;Color&gt; DefaultLineColors { get; set; }
}</code></pre><p>In the above code, we have a class that describes a <code>Chart</code> and that chart has a property with some <code>Options</code>. The property&apos;s type is <code>ChartOptions</code>, which is a base class that is common to all the different types of charts. There&apos;s a <code>LineChartOptions</code> class that inherits from <code>ChartOptions</code> and includes an additional property called <code>DefaultLineColors</code> that defines some colors for the lines of the line chart.</p><pre><code class="language-csharp">Chart chart = new Chart
{
    Options = new LineChartOptions
    {
        DefaultLineColors = new [] { Color.Red, Color.Purple, Color.Blue }
    }
};
string json = JsonSerializer.Serialize(chart);</code></pre><p>The value of <code>json</code> will be <code>{&quot;Options&quot;:{&quot;ShowLegend&quot;:false}}</code>. Note that it&apos;s missing the <code>DefaultLineColors</code> property. Why is that happening? It&apos;s because the behavior of <code>JsonSerializer</code> is to only serialize members of the types that are defined in the object hierarchy at compile time. In other words, the serializer looks at the <code>Chart</code> class and sees that the type of the <code>Options</code> property is <code>ChartOptions</code>, so it looks at the <code>ChartOptions</code> class&apos;s members and only sees <code>ShowLegend</code>, so that&apos;s the only thing that it serializes, even though the instance of the object inside of the <code>Options</code> property might be a subclass of <code>ChartOptions</code> that includes additional properties.</p><h2 id="solution">Solution</h2><p>So how do we get it to serialize all of the properties, including those defined in subtypes? Unfortunately, there&apos;s not a great answer to that question at the time of this writing. There are active discussions and complaints about this missing functionality <a href="https://github.com/dotnet/runtime/issues/29937">on GitHub</a>. The best solution I&apos;ve found thus far (aside from switching back to Newtonsoft.Json for serialization) is to use a customer <code>JsonConverter&lt;T&gt;</code>. An example of one such converter is below. Please note that <em>deserialization</em> has not been implemented.</p><pre><code class="language-csharp">public class PolymorphicJsonConverter&lt;T&gt; : JsonConverter&lt;T&gt;
{
    public override bool CanConvert(Type typeToConvert)
    {
        return typeof(T).IsAssignableFrom(typeToConvert);
    }

    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        if (value is null)
        {
            writer.WriteNullValue();
            return;
        }

        writer.WriteStartObject();
        foreach (var property in value.GetType().GetProperties())
        {
            if (!property.CanRead)
                continue;
            var propertyValue = property.GetValue(value);
            writer.WritePropertyName(property.Name);
            JsonSerializer.Serialize(writer, propertyValue, options);
        }
        writer.WriteEndObject();
    }
}</code></pre><p>Here&apos;s how to apply it.</p><pre><code class="language-csharp">Chart chart = new Chart
{
    Options = new LineChartOptions
    {
        DefaultLineColors = new[] { Color.Red, Color.Purple, Color.Blue }
    }
};
var options = new JsonSerializerOptions();
options.Converters.Add(new PolymorphicJsonConverter&lt;ChartOptions&gt;());
string json = JsonSerializer.Serialize(chart, options);
return JsonSerializer.Serialize(this, s_serializerOptions);</code></pre><p>The <code>PolymorphicJsonConverter&lt;T&gt;</code> is a generic type and an instance of that converter must be added to the <code>JsonSerializerOptions</code> for every root type in your inheritance hierarchy. For example, if you want to support polymorphic serialization for class <code>Baz</code> that inherits from class <code>Bar</code> that inherits from class <code>Foo</code>, then you&apos;d need to add an instance of <code>PolymoprhicJsonConverter&lt;Foo&gt;</code> to your serializer options.</p><p>Here&apos;s the correct JSON that was generated from the example above that uses <code>PolymorphicJsonConverter&lt;T&gt;</code>.</p><pre><code class="language-json">{
    &quot;Options&quot;:{
        &quot;DefaultLineColors&quot;:[
            {
                &quot;R&quot;:255,
                &quot;G&quot;:0,
                &quot;B&quot;:0,
                &quot;A&quot;:255,
                &quot;IsKnownColor&quot;:true,
                &quot;IsEmpty&quot;:false,
                &quot;IsNamedColor&quot;:true,
                &quot;IsSystemColor&quot;:false,
                &quot;Name&quot;:&quot;Red&quot;
            },
            {
                &quot;R&quot;:128,
                &quot;G&quot;:0,
                &quot;B&quot;:128,
                &quot;A&quot;:255,
                &quot;IsKnownColor&quot;:true,
                &quot;IsEmpty&quot;:false,
                &quot;IsNamedColor&quot;:true,
                &quot;IsSystemColor&quot;:false,
                &quot;Name&quot;:&quot;Purple&quot;
            },
            {
                &quot;R&quot;:0,
                &quot;G&quot;:0,
                &quot;B&quot;:255,
                &quot;A&quot;:255,
                &quot;IsKnownColor&quot;:true,
                &quot;IsEmpty&quot;:false,
                &quot;IsNamedColor&quot;:true,
                &quot;IsSystemColor&quot;:false,
                &quot;Name&quot;:&quot;Blue&quot;
            }
        ],
        &quot;ShowLegend&quot;:false
    }
}</code></pre>]]></content:encoded></item><item><title><![CDATA[WPF and MSTest]]></title><description><![CDATA[This post demonstrates a solution for overcoming the exception that is thrown when trying to test a WPF class with MSTest.]]></description><link>https://getyourbitstogether.com/wpf-and-mstest/</link><guid isPermaLink="false">5fc4bbb256418e1acce131b0</guid><category><![CDATA[wpf]]></category><category><![CDATA[csharp]]></category><dc:creator><![CDATA[Brandon Baker]]></dc:creator><pubDate>Mon, 30 Nov 2020 09:44:34 GMT</pubDate><content:encoded><![CDATA[<h2 id="problem">Problem</h2><p>I was recently trying to run a unit test containing a WPF class and received the following error during test execution: &quot;System.InvalidOperationException: &apos;The calling thread must be STA, because many UI components require this.&apos;&quot; This exception was thrown when I tried to instantiate a class that was derived from <code>System.Windows.Controls.UserControl</code>. It&apos;s complaining because only STA threads can create those types of classes and my unit test isn&apos;t an STA thread.</p><p>I did some Googling and just about every result that appeared was for NUnit, but I&apos;m using MSTest (MSTest.TestFramework), so I needed a solution for that framework specifically.</p><h2 id="solution">Solution</h2><p>The solution was actually really simple when I found <a href="https://www.meziantou.net/mstest-v2-customize-test-execution.htm">this link</a>. I created a <code>WpfTestMethodAttribute</code> class and then applied it to my unit tests.</p><p>Here&apos;s the <code>WpfTestMethodAttribute</code>. It is used instead of the normal <code>TestMethodAttribute</code> that MSTest provides.</p><pre><code class="language-csharp">public class WpfTestMethodAttribute : TestMethodAttribute
{
    public override TestResult[] Execute(ITestMethod testMethod)
    {
        if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
            return Invoke(testMethod);

        TestResult[] result = null;
        var thread = new Thread(() =&gt; result = Invoke(testMethod));
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
        thread.Join();
        return result;
    }

    private TestResult[] Invoke(ITestMethod testMethod)
    {
        return new[] { testMethod.Invoke(null) };
    }
}</code></pre><p>Here&apos;s a quick and dirty example of the attribute in use.</p><pre><code class="language-csharp">[TestClass]
public class MyTestClass
{
    [WpfTestMethod]
    public void MyWpfTest()
    {
        // The following line will fail unless executed on an STA thread.
        var userControl = new UserControl();
        Assert.IsNotNull(userControl);
    }
}</code></pre><p></p>]]></content:encoded></item><item><title><![CDATA[Fixing Relative WPF Bindings On Custom Properties]]></title><description><![CDATA[I recently spent a lot of time troubleshooting a problem where my relative WPF bindings were not behaving as expected for custom dependency properties that I had defined. This post explores the problem and the solution.]]></description><link>https://getyourbitstogether.com/fixing-relative-wpf-bindings/</link><guid isPermaLink="false">5fc1de5c56418e1acce1309c</guid><category><![CDATA[wpf]]></category><category><![CDATA[csharp]]></category><dc:creator><![CDATA[Brandon Baker]]></dc:creator><pubDate>Sat, 28 Nov 2020 07:21:17 GMT</pubDate><content:encoded><![CDATA[<h2 id="problem">Problem</h2><p>I was working on a custom WPF control recently and spent several hours trying to figure out why the bindings on my custom dependency properties weren&apos;t functioning correctly. The control was initially displayed in a <code>Collapsed</code> visibility state but then later became visible after user interaction. Within that control, I had some content that I wanted to display, but I wanted the content&apos;s color to be inherited from a parent control.</p><p>This problem only occured when the custom control was initially rendered with a <code>Collapsed</code> visibility. If the control started out as <code>Visible</code> or even <code>Hidden</code>, the bindings worked as expected.</p><p>The following is a derived, and greatly simplified example to illustrate the problem I was having. Please keep in mind that this coding style does not reflect best practices for production quality code. In this example, we have a Window that appears with a button in the middle of the screen that says &quot;Click me.&quot; We have a custom <code>FooteredContentControl</code> that should appear when the user clicks the button. The custom control should have text that says &quot;Body&quot; in the main <code>Content</code> property, and then we want to see an icon of a foot in the <code>Footer</code> property. Oh, and we want them both to inherit the hot pink color from the window. </p><p>The xaml below defines the <code>MainWindow</code> layout.</p><figure class="kg-card kg-code-card"><pre><code class="language-xml">&lt;Window
    x:Class=&quot;WpfApp1.MainWindow&quot;
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
    xmlns:local=&quot;clr-namespace:WpfApp1&quot;
    xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
    Title=&quot;MainWindow&quot;
    Width=&quot;800&quot;
    Height=&quot;450&quot;
    Foreground=&quot;HotPink&quot;
    mc:Ignorable=&quot;d&quot;&gt;
    &lt;Window.Resources&gt;
        &lt;ResourceDictionary&gt;
            &lt;ResourceDictionary.MergedDictionaries&gt;
                &lt;ResourceDictionary Source=&quot;FooteredContentControl.xaml&quot; /&gt;
            &lt;/ResourceDictionary.MergedDictionaries&gt;
            &lt;PathGeometry x:Key=&quot;PathGeometryFoot&quot; Figures=&quot;M16 2A2 2 0 1 1 14 4A2 2 0 0 1 16 2M12.04 3A1.5 1.5 0 1 1 10.54 4.5A1.5 1.5 0 0 1 12.04 3M9.09 4.5A1 1 0 1 1 8.09 5.5A1 1 0 0 1 9.09 4.5M7.04 6A1 1 0 1 1 6.04 7A1 1 0 0 1 7.04 6M14.53 12A2.5 2.5 0 0 0 17 9.24A2.6 2.6 0 0 0 14.39 7H11.91A6 6 0 0 0 6.12 11.4A2 2 0 0 0 6.23 12.8A6.8 6.8 0 0 1 6.91 15.76A6.89 6.89 0 0 1 6.22 18.55A1.92 1.92 0 0 0 6.3 20.31A3.62 3.62 0 0 0 10.19 21.91A3.5 3.5 0 0 0 12.36 16.63A2.82 2.82 0 0 1 11.91 15S11.68 12 14.53 12Z&quot; /&gt;
        &lt;/ResourceDictionary&gt;
    &lt;/Window.Resources&gt;
    &lt;DockPanel&gt;
        &lt;local:FooteredContentControl
            x:Name=&quot;Control&quot;
            DockPanel.Dock=&quot;Top&quot;
            Visibility=&quot;Collapsed&quot;&gt;
            &lt;local:FooteredContentControl.Footer&gt;
                &lt;Path
                    Width=&quot;20&quot;
                    Height=&quot;20&quot;
                    Data=&quot;{StaticResource PathGeometryFoot}&quot;
                    Fill=&quot;{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}, Path=Foreground}&quot;
                    Stretch=&quot;Uniform&quot; /&gt;
            &lt;/local:FooteredContentControl.Footer&gt;
            &lt;TextBlock Text=&quot;Body&quot; /&gt;
        &lt;/local:FooteredContentControl&gt;
        &lt;Button
            HorizontalAlignment=&quot;Center&quot;
            VerticalAlignment=&quot;Center&quot;
            Click=&quot;VisibilityToggle_Click&quot;
            Content=&quot;Click Me&quot; /&gt;
    &lt;/DockPanel&gt;
&lt;/Window&gt;</code></pre><figcaption>MainWindow.xaml</figcaption></figure><p>Here&apos;s the code-behind that drives <code>MainWindow</code> class behavior.</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">using System.Windows;

namespace WpfApp1
{
    /// &lt;summary&gt;
    /// Interaction logic for MainWindow.xaml
    /// &lt;/summary&gt;
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void VisibilityToggle_Click(object sender, RoutedEventArgs e)
        {
            Control.Visibility = Control.Visibility == Visibility.Visible ?
                Visibility.Collapsed : Visibility.Visible;
        }
    }
}</code></pre><figcaption>MainWindow.xaml.cs</figcaption></figure><p>The <code>FooteredContentControl</code> is the custom control that we&apos;re having problems with. It is defined below.</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">using System.Windows;
using System.Windows.Controls;

namespace WpfApp1
{
    public class FooteredContentControl : ContentControl
    {
        public static readonly DependencyProperty FooterProperty =
            DependencyProperty.Register(&quot;Footer&quot;, typeof(object), typeof(FooteredContentControl),
                new FrameworkPropertyMetadata(null));

        static FooteredContentControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(FooteredContentControl),
                new FrameworkPropertyMetadata(typeof(FooteredContentControl)));
        }

        public object Footer
        {
            get { return GetValue(FooterProperty); }
            set { SetValue(FooterProperty, value); }
        }
    }
}
</code></pre><figcaption>FooteredContentControl.cs</figcaption></figure><p>Here&apos;s the style for the <code>FooteredContentControl</code> that defines the visual layout.</p><figure class="kg-card kg-code-card"><pre><code class="language-xml">&lt;ResourceDictionary
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:local=&quot;clr-namespace:WpfApp1&quot;&gt;
    &lt;Style x:Key=&quot;{x:Type local:FooteredContentControl}&quot; TargetType=&quot;{x:Type local:FooteredContentControl}&quot;&gt;
        &lt;Setter Property=&quot;Template&quot;&gt;
            &lt;Setter.Value&gt;
                &lt;ControlTemplate TargetType=&quot;{x:Type local:FooteredContentControl}&quot;&gt;
                    &lt;StackPanel&gt;
                        &lt;ContentPresenter /&gt;
                        &lt;ContentPresenter ContentSource=&quot;Footer&quot; /&gt;
                    &lt;/StackPanel&gt;
                &lt;/ControlTemplate&gt;
            &lt;/Setter.Value&gt;
        &lt;/Setter&gt;
    &lt;/Style&gt;
&lt;/ResourceDictionary&gt;</code></pre><figcaption>FooteredContentControl.xaml</figcaption></figure><p>Everything else is standard, out-of-the-box WPF project files.</p><p>In the example above, we click the button and only the word &quot;Body&quot; shows up but we don&apos;t see any feet. After snooping around with debugging tools, you can see that the <code>Path</code> with the feet is actually there, but it&apos;s just not visible because the <code>Binding</code> in the path&apos;s <code>Fill</code> is not being evaluated correctly. Thus, the <code>Fill</code> which defines the color is set to <code>null</code>, rendering the feet effectively transparent. To solve this problem, the issue with the binding needs to be addressed.</p><h2 id="solution">Solution</h2><p>The solution was to make the value of my custom dependency property part of the logical tree. To accomplish this, a property changed callback was added to the <code>FooterProperty</code> and that callback method then invokes <code>RemoveLogicalChild</code> and <code>AddLogicalChild</code> to ensure that any footer content is added to the logical tree. This allows the relative binding to work as expected.</p><pre><code class="language-csharp">using System.Windows;
using System.Windows.Controls;

namespace WpfApp1
{
    public class FooteredContentControl : ContentControl
    {
        public static readonly DependencyProperty FooterProperty =
            DependencyProperty.Register(&quot;Footer&quot;, typeof(object), typeof(FooteredContentControl),
                new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnFooterPropertyChanged)));

        static FooteredContentControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(FooteredContentControl),
                new FrameworkPropertyMetadata(typeof(FooteredContentControl)));
        }

        public object Footer
        {
            get { return GetValue(FooterProperty); }
            set { SetValue(FooterProperty, value); }
        }

        /// &lt;summary&gt;
        /// This called by the dependency property when its value has changed.
        /// &lt;/summary&gt;
        /// &lt;remarks&gt;
        /// This is what was added to fix the bug
        /// that prevented the Footer content from showing
        /// when this control first appears in Collapsed
        /// visibility.
        /// &lt;/remarks&gt;
        /// &lt;param name=&quot;d&quot;&gt;&lt;/param&gt;
        /// &lt;param name=&quot;e&quot;&gt;&lt;/param&gt;
        private static void OnFooterPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var control = (FooteredContentControl)d;

            // The following methods are provided by the FrameworkElement base class.

            // Removes any old content from the logical tree.
            control.RemoveLogicalChild(e.OldValue);
            // Adds new content to the logical tree.
            control.AddLogicalChild(e.NewValue);
        }
    }
}
</code></pre><p>The demo code will now show the feet icon when the user clicks the button.</p>]]></content:encoded></item><item><title><![CDATA[Fire And Forget Tasks]]></title><description><![CDATA[This post demonstrates a couple of different ways to execute fire and forget tasks in C#.]]></description><link>https://getyourbitstogether.com/fire-and-forget-tasks/</link><guid isPermaLink="false">5f83d6d756418e1acce12fe7</guid><category><![CDATA[csharp]]></category><dc:creator><![CDATA[Brandon Baker]]></dc:creator><pubDate>Mon, 12 Oct 2020 05:21:17 GMT</pubDate><content:encoded><![CDATA[<p>In C#, sometimes you want to start a <code>Task</code> but you don&apos;t care about waiting for the result. But even though you may not care about the result of the task or how long it takes to complete, you shouldn&apos;t ignore the possibility of an error. At the very least, you&apos;ll probably want to log the error.</p><p>There are at least a couple of ways to execute fire and forget tasks. The first way is by running the task with a continuation. Here&apos;s how that&apos;s done.</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">static void FireAndForgetExample1(Task taskToForget)
{
    _ = taskToForget.ContinueWith(t =&gt;
    {
        if (t.IsFaulted)
        {
            // Log the exception.
        }
    });
}</code></pre><figcaption>Fire and forget with a continuation</figcaption></figure><p>The previous example uses <code>ContinueWith</code> which was popular before the <code>async</code> and <code>await</code> keywords were introduced. <a href="https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md#prefer-await-over-continuewith">It&apos;s now preferred to use the new key words instead of the older continuation style.</a> Here are a couple of reasons why:</p><ul><li><strong>It&apos;s easier to debug:</strong> The <code>await</code> keyword creates a state machine when your code is compiled and that state machine aids in your debugging.</li><li><strong>It&apos;s optimized:</strong> As mentioned above, the <code>await</code> keyword creates a state machine that is optimized for execution and can continue to be optimized in the future. One such optimization is that completed tasks return immediately. Conversely, <code>ContinueWith</code> is less efficient because it must allocate a continuation task for each continuation.</li></ul><p>Here&apos;s how to execute fire and forget tasks using a local function, which takes advantage of the <code>async</code> and <code>await</code> keywords.</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">static void FireAndForgetExample2(Task taskToForget)
{
    async Task Forget(Task task)
    {
        try
        {
            await task;
        }
        catch (Exception ex)
        {
            // Log the exception.
        }
    }
    _ = Forget(taskToForget);
}</code></pre><figcaption>Fire and forget with a local function</figcaption></figure>]]></content:encoded></item><item><title><![CDATA[WPF Version Numbers]]></title><description><![CDATA[This post examines a couple of different ways that WPF version numbers can be stored and retrieved.]]></description><link>https://getyourbitstogether.com/wpf-version-numbers/</link><guid isPermaLink="false">5f6029ae56418e1acce12ef7</guid><category><![CDATA[csharp]]></category><category><![CDATA[wpf]]></category><dc:creator><![CDATA[Brandon Baker]]></dc:creator><pubDate>Tue, 15 Sep 2020 03:31:46 GMT</pubDate><content:encoded><![CDATA[<p>It&apos;s important to display the version of your WPF application somewhere in the user interface, but before you can display it, you need to know how to store and retrieve it. There are at least a couple of ways this can be accomplished and that&apos;s what we&apos;ll examine in this post.</p><h2 id="version-property">Version Property</h2><p>The most straightforward and popular approach is simply to use the <code>Version</code> property from the assembly&apos;s name. This can be set by right-clicking on the project and setting the Assembly version within the project&apos;s properties. In a .NET Framework app, this is found under the Application -&gt; Assembly Information section of the project&apos;s properties, while in .NET Core, it can be found in the Package section of the project&apos;s properties.</p><p>Here&apos;s how you can read the value in code.</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">// Retrieve the assembly that contains this code.
// If this code lives in a DLL, you might want to use
// Assembly.GetEntryAssembly() instead.
var assembly = Assembly.GetExecutingAssembly();
// Get the version from the assembly.
var version = assembly.GetName().Version.ToString();</code></pre><figcaption>How to read the Version property from an assembly</figcaption></figure><h2 id="assemblyinformationalversionattribute">AssemblyInformationalVersionAttribute</h2><p>Sometimes you might want to describe your version as a string instead of a series of octets. For example, maybe your version is &quot;2.0.0-alpha.3&quot;. If you want to describe your version in this way, then you won&apos;t be able to use the <code>Version</code> property mentioned above because it limits you to four integer octets, like &quot;3.0.1.0&quot;.</p><p>The AssemblyInformationalVersionAttribute can be used to specify a string with version info. This will display a warning if the string is not in the format that is used by the assembly&apos;s version number, or if the string contains wildcard characters, but the warning can be ignored.</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">// Retrieve the assembly that contains this code.
// If this code lives in a DLL, you might want to use
// Assembly.GetEntryAssembly() instead.
var assembly = Assembly.GetExecutingAssembly();
// Search the assembly attributes for the informational
// version number and return the first one found or
// null if none were found for this assembly.
var version = assembly
    .GetCustomAttributes&lt;AssemblyInformationalVersionAttribute&gt;()
    .Select(x =&gt; x.InformationalVersion)
    .FirstOrDefault();</code></pre><figcaption>How to read AssemblyInformationalVersionAttribute</figcaption></figure><h3 id="-net-framework">.NET Framework</h3><p>If your application runs on the traditional .NET Framework, then you&apos;ll want to ensure that you have the attribute added to the AssemblyInfo.cs file.</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">using System.Reflection;

[assembly: AssemblyInformationalVersion(&quot;1.0.0-alpha.4&quot;)]</code></pre><figcaption>AssemblyInformationalVersion in AssemblyInfo.cs of .NET Framework project</figcaption></figure><h3 id="-net-core">.NET Core</h3><p>If you&apos;re using .NET Core, the AssemblyInformationalVersionAttribute is automatically added and is based on the <code>&lt;Version&gt;&lt;/Version&gt;</code> element in the csproj file.</p><figure class="kg-card kg-code-card"><pre><code class="language-xml">&lt;PropertyGroup&gt;
    &lt;OutputType&gt;WinExe&lt;/OutputType&gt;
    &lt;TargetFramework&gt;netcoreapp3.1&lt;/TargetFramework&gt;
    &lt;UseWPF&gt;true&lt;/UseWPF&gt;
    &lt;LangVersion&gt;8.0&lt;/LangVersion&gt;
    &lt;Nullable&gt;enable&lt;/Nullable&gt;
    &lt;!-- This populates the AssemblyInformationalVersionAttribute --&gt;
    &lt;Version&gt;1.0.0-alpha.4&lt;/Version&gt;
&lt;/PropertyGroup&gt;</code></pre><figcaption>AssemblyInformationalVersion being derived from csproj in .NET Core project</figcaption></figure><p>If your application still explicitly defines an AssemblyInformationalVersionAttribute inside of your .NET Core project, then you&apos;ll get an error that states &quot;Duplicate &apos;System.Reflection.AssemblyInformationalVersionAttribute&apos; attribute&quot;. The easy way to resolve this is just to delete the attribute from your code (typically located in AssemblyInfo.cs) and just use the <code>&lt;Version&gt;&lt;/Version&gt;</code> xml element inside of your csproj instead.</p>]]></content:encoded></item><item><title><![CDATA[Changing Entity Framework Core Migrations Folder]]></title><description><![CDATA[Want your Entity Framework Core migrations to land in a folder other than the default Migrations folder? Here's how to fix that.]]></description><link>https://getyourbitstogether.com/changing-entity-framework-core-migrations-folder/</link><guid isPermaLink="false">5f45c8b856418e1acce12ebc</guid><category><![CDATA[efcore]]></category><dc:creator><![CDATA[Brandon Baker]]></dc:creator><pubDate>Wed, 26 Aug 2020 02:39:27 GMT</pubDate><content:encoded><![CDATA[<p>By default, Entity Framework Core migrations will put your migration code inside of a Migrations folder in the root of your project. This isn&apos;t always desirable, but luckily changing the output folder is easy. All you need to do is specify the option <code>-o</code> followed by the desired path. The example below will output migration code into the Migrations folder located within the Model folder.</p><figure class="kg-card kg-code-card"><pre><code>dotnet ef migrations add Initial -o Model\Migrations</code></pre><figcaption>Example of -o usage</figcaption></figure><p>Note that you&apos;ll only need to specify the output argument for the first migration. Entity Framework Core is smart enough to put future migrations in the correct folder.</p>]]></content:encoded></item><item><title><![CDATA[Notify Collection Changed Event Args Reference]]></title><description><![CDATA[If you're like me and find yourself forgetting how the event args work in INotifyCollectionChanged, then here's a quick reference that might be useful.]]></description><link>https://getyourbitstogether.com/notifycollectionchangedeventargs/</link><guid isPermaLink="false">5efac21156418e1acce12d9a</guid><category><![CDATA[csharp]]></category><dc:creator><![CDATA[Brandon Baker]]></dc:creator><pubDate>Tue, 30 Jun 2020 05:09:57 GMT</pubDate><content:encoded><![CDATA[<p>I end up using <code>INotifyCollectionChanged</code> frequently, but not frequently enough to reliably recall how <code>NotifyCollectionChangedEventArgs</code> works when it is raised from the <code>INotifyCollectionChanged.CollectionChanged</code> event. There&apos;s a <a href="https://blog.stephencleary.com/2009/07/interpreting-notifycollectionchangedeve.html">nice post by Stephen Cleary</a> that summarizes how this works, but I wanted to take a minute to try to improve the formatting.</p><h2 id="add">Add</h2><p>The <code>Action</code> is <code>NotifyCollectionChangedAction.Add</code> when items are added to the collection.</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>NewItems</code></td>
<td>Contains any items that were added.</td>
</tr>
<tr>
<td><code>NewStartingIndex</code></td>
<td>Index where new items were added, otherwise <code>-1</code>.</td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><h2 id="remove">Remove</h2><p>The <code>Action</code> is <code>NotifyCollectionChangedAction.Remove</code> when items are removed from the collection.</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>OldItems</code></td>
<td>Contains any items that were removed.</td>
</tr>
<tr>
<td><code>OldStartingIndex</code></td>
<td>Index where where items were removed, otherwise <code>-1</code>.</td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><h2 id="replace">Replace</h2><p>The <code>Action</code> is <code>NotifyCollectionChangedAction.Replace</code> when old items are replaced with new items.</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>NewItems</code></td>
<td>Contains items that are replacing old items.</td>
</tr>
<tr>
<td><code>NewStartingIndex</code></td>
<td>Equal to <code>OldStartingIndex</code>.</td>
</tr>
<tr>
<td><code>OldItems</code></td>
<td>Contains the items that were replaced by new items.</td>
</tr>
<tr>
<td><code>OldStartingIndex</code></td>
<td>Contains the index from which the old items were removed.</td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><h2 id="move">Move</h2><p>The <code>Action</code> is <code>NotifyCollectionChangedAction.Move</code> when one or more items are moved within the collection. This operation is logically treated as a <code>Remove</code> followed by an <code>Add</code>, so <code>NewStartIndex</code> is interpreted as though the items had already been removed.</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>NewItems</code></td>
<td><code>SequenceEqual</code> to <code>OldItems</code>, though they may be different instances.</td>
</tr>
<tr>
<td><code>NewStartingIndex</code></td>
<td>Contains the index to which the items were moved.</td>
</tr>
<tr>
<td><code>OldItems</code></td>
<td>Contains the items that were moved.</td>
</tr>
<tr>
<td><code>OldStartingIndex</code></td>
<td>Contains the index from which the items were moved.</td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><h2 id="reset">Reset</h2><p>The <code>Action</code> is <code>NotifyCollectionChangedAction.Reset</code> when a collection is completely reset. None of the properties in the event args will have values.</p>]]></content:encoded></item></channel></rss>