Tag Archives: Data

Creating a Running Game in VueJS – Part 3 – Component Files and Installing Vue

This is the third part in a series on replicating a game similar (in some respects) to the ZX Spectrum game “Daley Thompson’s Decathlon”.

To start from the beginning of the series, go here.

In this particular post, we’ll be continuing our refactor by moving out components into their own files.

If you’d like to see the code from this post then it’s on GitHub here.

Install Vue and Create a New App

The first thing you’ll need to do here is to install Vue:

npm install vue

Once this is done, we’ll just create a brand new templated Vue project:

vue create vue-app

What we’re essentially going to do here is to copy our existing program from part 2 into the new application, but using separate files for components. All we actually have now is a single file (index.html).

Copying Code

Your new app should look broadly like this:

Let’s start by creating a new component called Timer, this will be the successor for our seconds-remaining component:

Now, let’s take the code from our component and paste it in. We’ll start with the template; the current template is:

template: `
    <p>Seconds remaining: {{ seconds }}</p>
`

And that will become:

<template>
    <p>Seconds remaining: {{ seconds }}</p>
</template>

Next we need the props; so the following:

props: ['seconds'],

Will become:

<script>
export default {
  name: 'Timer',
  props: {
    seconds: Number
  }
}
</script>

Since we have no style, that’s done:

Next, we’ll bring across the player component in the same way:

The next stage is to update App.vue component. The template will now look like this:

<template>
  <Player
      v-bind:location="location">
  </Player>
  <Timer 
      v-bind:seconds="secondsRemaining">
  </Timer>            
</template>

Inside the script tag, we’ll bring in the Player and Timer components:

<script>
    import Player from './components/Player.vue'
    import Timer from './components/Timer.vue'

Next, we need to define which components we’re using:

export default {
  name: 'App',
  components: {    
    Player,
    Timer
  },

We then need our data tag, which now needs to be a function:

  data: function() {                    
    return {
      playerX: 100,
      playerY: 100,
      speed: 0,
      toggleSpeed: 1,                    
      startTime: 0,
      timeNow: 0
    };
  },

The rest can come across as is (please see the GitHub repo for these).

Finally, you can remove HelloWorld.vue.

Now that we have the code inside components, in the next part, we’ll add a finish line, and a way for the player to win or lose.

Creating a Running Game in VueJS – Part 1 – Moving

If, like me, you’re over the age of 35, you may have owned a Spectrum, Amstrad, or Commodore 64. One of the games, especially on the Spectrum, that was guaranteed to ruin your keyboard, and make your family think you were having some kind of fit, was Daley Thomson’s Decathlon.

In this post, I introduced the basics of writing a game in VueJS. In this series of posts, I’m going to try to recreate that game, at least in spirit. I’m afraid I won’t have the amazing graphics, but hopefully we can create something vaguely similar.

I’ll be putting the various parts in GitHub here. I made a similar series of posts using React; you can find them here.

In this first section, we’ll create a player (it’ll just be a box on the screen for now), and a timer. To get the code, look here.

Let’s start by seeing the HTML:

<div id="app">
    <div v-bind:style="location"></div>
    <p>{{ secondsRemaining }}</p>
</div>

We’re simply binding the style of the div to one computed property, and secondsRemaining is another. Let’s see what the computed section looks like next:

computed: {                    
    location: function() {
        return 'width:10px; height:10px; left:' + this.playerX + 'px; top:' + this.playerY + 'px; border:1px solid #000; position: absolute;';
    },
    secondsRemaining: function() {
        const diff = (this.startTime - this.timeNow) / 1000;
        return Math.round(diff);
    }
},

Remember that this section will cause a screen refresh when the variables it uses change; it does not know that the function will return a different value otherwise; which is why I’m not getting the current time inside the secondsRemaining function.

The location will force an update when the playerX or playerY properties change. Let’s see the data:

data: {                    
     playerX: 100,
     playerY: 100,
     speed: 0,
     toggleSpeed: 1,                    
     startTime: 0,
     timeNow: 0
},

There’s just two more set-up points – the first is the mounted() method:

mounted() {
    this.init();
}

This is another lifecycle event; it’s called late on in the start-up process, after everything is created. We’ll come back to Init() shortly.

Next we have created(): this is early on in the lifecycle, and here we’re just going to create an event listener:

created() {
    window.addEventListener('keydown', this.onKeyDown);
},

That’s pretty much all the set-up. Everything else is in the methods() section. Let’s start with the init() method that we saw earlier:

init() {
    setInterval(this.update, 10);
    this.startTime = new Date();
    this.startTime.setSeconds(this.startTime.getSeconds() + 20);
},

All we’re doing here is initialising the timer, and creating an update loop. Let’s see the update() method next:

update() {
    this.playerX += this.speed;
    if (this.speed > 0) {
        this.speed -= 0.01;
    } else {
        this.speed = 0;
    }
    this.timeNow = new Date().getTime();
}

This is the update method, but it’s more akin to a draw method: it’s limited to updating the variables that force a screen update. It also slows the runner down naturally (so if the player does nothing, the character will stop).

There’s just one more thing we have yet to see, and that’s the method that handles the keypress; which, in fact, is two methods:

onKeyDown(e) {                        
    switch (e.which) {
        case 37: // Left
            this.playerRun(1); 
            break;
        case 39: // Right
            this.playerRun(2); 
            break;
        default:
            break;
    }
},
                    
playerRun(toggle) {                        
    if (this.toggleSpeed !== toggle) {                           
        this.speed += 0.12;
        this.toggleSpeed = toggle;
    }
},                  

One of the defining features of the original game was that you ran by pressing the left key, and then the right in quick succession; we’ve emulated this by simply setting a flag, and comparing them.

That’s it, the first part complete:

I know you’re probably wondering how I managed to great such amazing graphics!

The code works (after a fashion), but it’s messy. In Part 2, we’ll refactor this code into components.

Vue Basics – Moving Objects Around the Screen

I’ve recently been playing around with Vue. One of the things that I typically do when I’m learning some kind of front-end technology, is to work out how I might write a game in that technology – that usually tests the boundaries of what you can do. If you’re interested, this is a car game that I created in React.

Let’s start by having a look at what a bog standard “Hello World” app looks like in Vue:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Testing Vue</title>
    </head>
    <body>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
        
        <div id="app">
            <h1>{{ title }}</h1>
        </div>
        <script>
            new Vue({
                el: '#app',
                data: {
                    title: 'Hello World'
                }
            });
        </script>        
    </body>
</html>

Another way that you can write that, would be like this:

<p v-text="testdata"></p>

This kind of synthax actually lets you bind any property, for example:

<h1 v-bind:title="testdata"></h1>

That’s pretty much the bit that I was looking for; if you can bind the title, then you can bind the style; for example:

<div v-bind:style="location">test</div>

Inside the data section, I can expose a location; for example:

new Vue({
    el: '#app',
    data: {
        testdata: 'some data',
        location: 'width: 500px; height: 100px; left: 20px;border: 1px solid #000; position: absolute;'
                    
    },

Okay, so now we’re binding the style to a piece of data, so can we now do something like this:

data: {
    testdata: 'some data',
    posx: 100,
    location: 'width: 500px; height: 100px; left:' + this.posx + 'px; border: 1px solid #000; position: absolute;'
},

Unfortunately (or perhaps fortunately, I haven’t decided yet) not. Anything that changes needs to be in a separate section, called computed:

data: {
    testdata: 'some data',
    posx: 100                    
},
computed: {                    
    location: function() {
        return 'width:500px; height:100px; left:' + this.posx + 'px; border:1px solid #000; position: absolute;';
    } 
},

We’re actually nearly there now; all that’s missing is the thing that actually updates the variable, and therefore moves the div across the screen. The next thing we come across is the mounted method – this is a lifecycle event for each component, so we’ll need that to initialise our timer; now we can do this:

methods: {
    init() {
        setInterval(this.moveObject, 10);
    },
    moveObject() {
        this.posx += 1;                        
    }
},
mounted() {
    this.init();
}

It’s not hugely exciting, I’ll grant you, but moving an object around a screen is the basis for any game. For completeness, here’s the full code:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Testing Vue</title>
    </head>
    <body>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
        <div id="app">
            <h1>{{ testdata }}</h1>
            <p v-text="testdata"></p>
            <div v-bind:style="location">test</div>
        </div>
        <script>
            new Vue({
                el: '#app',
                data: {
                    testdata: 'some data',
                    posx: 100                    
                },
                computed: {                    
                    location: function() {
                        return 'width:500px;height:100px; left:' + this.posx + 'px;border:1px solid #000; position: absolute;';
                    } 
                },
                methods: {
                    init() {
                        setInterval(this.moveObject, 10);
                    },
                    moveObject() {
                        this.posx += 1;                        
                    }
                },
                mounted() {
                    this.init();
                }
            });
            
        </script>        
    </body>
</html>

References

Vue.js Tutorial From Scratch – e01 – Introduction, Installation & Outputting Data

CORS Errors while playing with the HTML Canvas

In this post, I wrote about how you might draw a graph using the HTML canvas; my next step was to make that more efficient; however, upon trying to import a Javascript module into my script:

import animatedGraphics from './animatedGraphics';

I started getting this error:

Access to script at ‘file:///C:/repos/webanimations/animated-columns-optimised/columns.js’ from origin ‘null’ has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

After a bit of digging, I uncovered a feature of ES6 that prevents opening this directly in a browser.

Hosting the site locally

The issue is caused because the file is being opened directly; so there seemed to be a couple of ways around this: one is to disable the security in Chrome, although try as I might, I couldn’t manage to get it to give up the ghost: I tried various combinations around the –disable-web-security flag of Chrome.

The second option is to host the site locally. For a brief moment I considered using something like IIS Express; but fortunately, I came across this tool that hosts a site locally for you.

It can be installed as an npm package:

npm install --global http-server

Once installed, you just navigate to the relevant directory, and type http-server:

C:\repos\webanimations\animated-columns-optimised>http-server
Starting up http-server, serving ./
Available on:
  http://192.168.1.79:8080
  http://127.0.0.1:8080
  http://172.17.230.225:8080
Hit CTRL-C to stop the server

You can then navigate to your specific page; for example:

http://127.0.0.1:8080/columns

And no more CORS error (doesn’t quite work yet, but that’s a whole different story).

Asp.Net Core 2.0 – Passing data into a Model Using DI

Imagine you have an Asp.Net Core web page, and you would like to edit some data in a form, but you’d like to default that data to something (maybe initially specified in the Web.Config).

I’m sure there’s dozens of ways to achieve this; but this is one.

Let’s start with a bog standard MVC web app:

Step one is to define a model in which to hold your data; here’s mine:

public class CurrentAppData
{
    public string DataField1 { get; set; }
}

Let’s register that in the IoC container:

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });
 
 
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
 
    services.AddTransient<CurrentAppData, CurrentAppData>(
        a => new CurrentAppData()
        {
            DataField1 = "test value"
        });

Next thing we’ll need is a View, and a corresponding view model to edit our data; here’s the view:

@model EditDataViewModel
@{
    ViewData["Title"] = "Edit Data";
}
 
<h2>@ViewData["Title"]</h2>
 
<div>
    <label>Change data here:</label>
    <input type="text" asp-for="EditData.DataField1" />
 
</div>

And now the view model (that is, the model that is bound to the view):

public class EditDataViewModel
{
    public EditDataViewModel(CurrentAppData editData)
    {
        EditData = editData;
    }
    public CurrentAppData EditData { get; set; }
}

The final step here is to adapt the controller so that the CurrentAppData object is passed through the controller:

public class EditDataController : Controller
{
    private readonly CurrentAppData _currentAppData;
 
    public EditDataController(CurrentAppData currentAppData)
    {
        _currentAppData = currentAppData;
    }
 
    public IActionResult EditData()
    {
        return View(new EditDataViewModel(_currentAppData));
 
 
    }
}

That works as far as it goes, and we now have the data displayed on the screen:

The next step is to post the edited data back to the controller; let’s change the HTML slightly:

<form asp-action="UpdateData" asp-controller="EditData" method="post" enctype="multipart/form-data">
    <label>Change data here:</label>
    <input type="text" asp-for="EditData.DataField1" />
    <br />
    <button type="submit" class="btn-default">Submit Changes</button>
</form>

We’ve added a submit button, which should cause the surrounding form element to execute whichever “method” it’s been told to (in this case, POST). It will look for an action on the controller called UpdateData, so we should create one:

public IActionResult UpdateData(EditDataViewModel editDataViewModel)
{
    System.Diagnostics.Debug.WriteLine(editDataViewModel.EditData.DataField1);
    return View("EditData", editDataViewModel);
}

Here, we’re accepting the EditDataViewModel from the view. However; when we run this, we get the following error:

Error:

InvalidOperationException: Could not create an instance of type ‘WebApplication14.Models.EditDataViewModel’. Model bound complex types must not be abstract or value types and must have a parameterless constructor. Alternatively, give the ‘editDataViewModel’ parameter a non-null default value.

Let’s first implement a fix for this, and then go into the whys and wherefores. The fix is actually quite straightforward; simply give the view model a parameterless constructor:

public class EditDataViewModel
{
    public EditDataViewModel()
    {
        
    }
 
    public EditDataViewModel(CurrentAppData editData)
    {
        EditData = editData;
    }
    public CurrentAppData EditData { get; set; }
}

The problem that we had here is that the `EditDataViewModel` that is returned to UpdateData is a new instance of the model. We can prove this by changing our code slightly:

Here, we’ve added a field called TestField1 to the model, and populated it just before we pass the model to the view; and on the post back, it’s gone. I’m not completely sure why the view model can’t be created by the middleware in the same way that the controller is; but that’s the subject of another post.

Finally, show the value back to the screen

To wrap up, we’ll just show the same value back to the screen; we’ll add an extra value to the model:

public class CurrentAppData
{
    public string DataField1 { get; set; }
 
    public string DisplayField1 { get; set; }
}

And we’ll just display it in the view:

<form asp-action="UpdateData" asp-controller="EditData" method="post" enctype="multipart/form-data">
    <label>Change data here:</label>
    <input type="text" asp-for="EditData.DataField1" />
    <br />
    <button type="submit" class="btn-default">Submit Changes</button>
    <br />
    <label>@Model.EditData.DisplayField1</label>
    <br />
</form>

Finally, we’ll copy that value inside the controller (obviously, this is simulating something meaningful happening), and then display the result:

public IActionResult UpdateData(EditDataViewModel editDataViewModel)
{
    editDataViewModel.EditData.DisplayField1 = editDataViewModel.EditData.DataField1;
    return View("EditData", editDataViewModel);
}

Let’s see what that looks like:

Playing with Azure Event Hub

I’ve recently been playing with the Azure Event Hub. This is basically a way of transmitting large amounts* of data between systems. In a later post, I may try and test these limits by designing some kind of game based on this.

As a quick disclaimer, it’s worth bearing in mind that I am playing with this technology, and so much of the content of this post can be found in the links at the bottom of this post – you won’t find anything original here – just a record of my findings. You may find more (and more accurate) information in those.

Event Hub Namespace

The first step, as with many Azure services, is to create a namespace:

For a healthy amount of data transference, you’ll pay around £10 per month.

Finally, we’ll create event hub within the namespace:

When you create the event hub, it asks how many partitions you need. This basically splits the message delivery; and it’s clever enough to work out, if you have 3 partitions and two listeners that one should have two slots, and one, one slot:

We’ll need an access policy so that we have permission to listen:

New Console Apps

We’ll need to create two applications: a producer and a consumer.

Let’s start with a producer. Create a new console app and add this NuGet library.

Here’s the code:

class Program
{
    private static EventHubClient eventHubClient;
    private const string EhConnectionString = "Endpoint=sb://pcm-testeventhub.servicebus.windows.net/;SharedAccessKeyName=Publisher;SharedAccessKey=key;EntityPath=pcm-eventhub1";
    private const string EhEntityPath = "pcm-eventhub1";
 
    public static async Task Main(string[] args)
    {
        EventHubsConnectionStringBuilder connectionStringBuilder = new EventHubsConnectionStringBuilder(EhConnectionString)
        {
            EntityPath = EhEntityPath
        };
 
        eventHubClient = EventHubClient.CreateFromConnectionString(connectionStringBuilder.ToString());
 
        while (true)
        {
            Console.Write("Please enter message to send: ");
            string message = Console.ReadLine();
            if (string.IsNullOrWhiteSpace(message)) break;
 
            await eventHubClient.SendAsync(new EventData(Encoding.UTF8.GetBytes(message)));
        }
 
        await eventHubClient.CloseAsync();
 
        Console.WriteLine("Press ENTER to exit.");
        Console.ReadLine();
    }
}

Consumer

Next we’ll create a consumer; so the first thing we’ll need is to grant permissions for listening:

We’ll create a second new console application with this same library and the processor library, too.

class Program
{
    private const string EhConnectionString = "Endpoint=sb://pcm-testeventhub.servicebus.windows.net/;SharedAccessKeyName=Listener;SharedAccessKey=key;EntityPath=pcm-eventhub1";
    private const string EhEntityPath = "pcm-eventhub1";
    private const string StorageContainerName = "eventhub";
    private const string StorageAccountName = "pcmeventhubstorage";
    private const string StorageAccountKey = "key";
 
    private static readonly string StorageConnectionString = string.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}", StorageAccountName, StorageAccountKey);
 
    static async Task Main(string[] args)
    {
        Console.WriteLine("Registering EventProcessor...");
 
        var eventProcessorHost = new EventProcessorHost(
            EhEntityPath,
            PartitionReceiver.DefaultConsumerGroupName,
            EhConnectionString,
            StorageConnectionString,
            StorageContainerName);
 
        // Registers the Event Processor Host and starts receiving messages
        await eventProcessorHost.RegisterEventProcessorAsync<EventsProcessor>();
 
        Console.WriteLine("Receiving. Press ENTER to stop worker.");
        Console.ReadLine();
 
        // Disposes of the Event Processor Host
        await eventProcessorHost.UnregisterEventProcessorAsync();
    }
}

class EventsProcessor : IEventProcessor
{
    public Task CloseAsync(PartitionContext context, CloseReason reason)
    {
        Console.WriteLine($"Processor Shutting Down. Partition '{context.PartitionId}', Reason: '{reason}'.");
        return Task.CompletedTask;
    }
 
    public Task OpenAsync(PartitionContext context)
    {
        Console.WriteLine($"SimpleEventProcessor initialized. Partition: '{context.PartitionId}'");
        return Task.CompletedTask;
    }
 
    public Task ProcessErrorAsync(PartitionContext context, Exception error)
    {
        Console.WriteLine($"Error on Partition: {context.PartitionId}, Error: {error.Message}");
        return Task.CompletedTask;
    }
 
    public Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
    {
        foreach (var eventData in messages)
        {
            var data = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);
            Console.WriteLine($"Message received. Partition: '{context.PartitionId}', Data: '{data}'");
        }
 
        return context.CheckpointAsync();
    }
}

As you can see, we can now transmit data through the Event Hub into client applications:

Footnotes

*Large, in terms of frequency, rather than volume – for example, transmitting a small message twice a second, rather than uploading a petabyte of data

References

https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-dotnet-standard-getstarted-send

https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-dotnet-standard-getstarted-receive-eph

Creating Complex Tables using SQLite.Net

Based on this earlier post, I returned to my test project to find that it didn’t actually pass anymore. The first issue was that the test couldn’t locate Sqllite3.dll.

Thanks to this question on every programmers favourite web site, I realised that I needed to add an extension for SQLite.

The next issue was when I tried to add a test to create a complex table:

complex1

Don’t know about [EntityName].

What I mean by a complex table, and the thing that CreateTable doesn’t like, is an entity that references another entity (the same is true if you try to reference the same entity).

Finally, you’re not allowed to use the System.Object type:

Complex2

A fix

It is my understanding that, if you can get it to work with SQLite, Entity Framework will solve this problem for you. I took more of a roll-your-own approach. The key issue here is that you want SQLite to not try to serialise the second object; and for this, you can use the [Ignore] attribute:

private ProductCategory _category;
 
[Ignore]
public ProductCategory Category
{
    get { return _category; }
    set
    {
        _category = value;
        RaisePropertyChanged();
    }
}

So, that stops it crashing. The next part is largely dependent on your data: if you have a basic primary / foreign key one-to-n mapping then this will work; however, anything more complex, and you’ll probably have to write a custom abstraction for the data. All that said, my solution starts with a base entity class:

public abstract class BaseDataEntity : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
 
    protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
 
    public abstract string Key { get; set; }
}

The PropertyChanged goes without saying (it’s like the roads), but the interesting part is the Key. Based on the code above, each entity needs a uniquely identifiable key; in this case, it’s a string; however, this can be any primitive type. In the derived class, you’ll need to map the type to the data; for example:

 
[Ignore]
public ProductCategory Category
{
    get { return _category; }
    set
    {
        _category = value;
        RaisePropertyChanged();
    }
}
 
public string CategoryRef
{
    get { return Category.Key; }
    set
    {
        if (Category == null)
        {
            Category = new ProductCategory()
            {
                Key = value
            };
        }
    }
}        

I’ll explain CategoryRef later on.

The next thing is to put some logic into the data access (I simply created a DataAccessBase class to sit on top of the SQLite data manipulation. Here is the abstraction to add a record:

 
public void Add(Type objType, object t)
{
    _connection.Insert(t);
 
    // Look for any ignored properties
    var ignored = objType                
        .GetProperties().Where(p =>
            p.CustomAttributes.Any(a => a.AttributeType == typeof(SQLite.Net.Attributes.IgnoreAttribute)));
 
    // For each, look for a reference
    foreach (var p in ignored)
    {
        // Determine the type first and get the value
        Type propertyType = p.PropertyType;
        var propertyValue = p.GetValue(t);
 
        // Recursively call this function to add the reference
        Add(propertyType, propertyValue);
    }
}

As you can see, for each reference, it simply recursively calls itself to add that, too. This will spectacularly fall down if you have a circular reference (so don’t do that, or don’t use this if you do).

Next is the Get:

 

public T Get<T>(string key) where T : class
{
    T data = _connection.Get<T>(key);
 
    var ignored = typeof(T)
        .GetProperties()
        .Where(p => p.GetCustomAttributes(typeof(SQLite.Net.Attributes.IgnoreAttribute), inherit: true).Any())
        .ToList();
 
    // For each, look for a reference
    foreach (var p in ignored)
    {
        // Get the reference property
        string propName = $"{p.Name}Ref";
        PropertyInfo refProp = typeof(T).GetProperty(propName);
 
        // Get its value (we know it's a string)
        string val = refProp.GetValue(data).ToString();
 
        // Determine the type first and get the value
        Type propertyType = p.PropertyType;
        
        var mapping = _connection.TableMappings.First(m => m.MappedType == propertyType);
        var rec = _connection.Find(val, mapping);
 
        // Update the property
        p.SetValue(data, rec);
 
    }
}

Here, I’m using a convention based approach; so, where I reference a separate class, I also have separate property called [Class]Ref; which you can see earlier on in the example of the entity code.

Conclusion

And that’s it; I make no assertions about edge cases, but for basic data that references other basic data, this works fine.

Acknowledgements

I have a great deal of help in creating this, but mainly just from random search results; however, I did ask a question on Stack Overflow

SQL Server quick insert test data

I recently came across a little known feature of SSMS that made me think that, for small amounts of data, it may be possible to create a procedure to insert test data into a table. Let’s start with the table:

CREATE TABLE [dbo].[Audit](
	[AuditDate] [datetime] NOT NULL,
	[AuditText] [varchar](max) NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

So, let’s create a statement that will inset data into this table:

INSERT INTO DBO.[Audit]
(AuditDate, AuditText)
VALUES
(GETDATE(), 'The sky is blue')

GO

sql1

Okay, so here’s the thing; try this:

INSERT INTO DBO.[Audit]
(AuditDate, AuditText)
VALUES
(GETDATE(), 'The sky is blue')

GO 10

sql2

So, that’s good, but what if you want some actual kosher data?

Randomising a date is relatively easy, using a combination of the RAND() function and the DATEADD() functions, you can do this in a single line. However, randomising text is more complex. If you just want random strings of letters, then you could try something like this. However, if you want something more sensible, then you can use a lookup table:

DECLARE @lookupTable TABLE (TextLookup VARCHAR(255))
DECLARE @lookupTableSize INT

INSERT INTO @lookupTable
(TextLookup)
VALUES
('red'), ('blue'), ('green'), ('orange'), ('purple')

SELECT @lookupTableSize = COUNT(1) FROM @lookupTable

INSERT INTO dbo.[Audit]
(AuditDate, AuditText)
VALUES
(DATEADD(day, -ABS(CHECKSUM(NewId())) % 30000, GETDATE()),
(SELECT TOP 1 TextLookup FROM (
    SELECT TextLookup, ROW_NUMBER() OVER (ORDER BY TextLookup) AS RowNum
    FROM @lookupTable
) AS DerivedAudit
WHERE DerivedAudit.RowNum >= (ABS(CONVERT(BIGINT,CONVERT(BINARY(8), NEWID()))) % @lookupTableSize) + 1))

GO 100


SELECT *
FROM dbo.Audit

It’s worth noting that GO in this case executes the entire script, not just the bit you want; however, I’m not proposing you use this for any serious volume – just for add a quick few records.

Implementing single cell copy and full row Item Selection in WPF DataGrid

Recently, I came across a strange problem with a DataGrid while using the MVVM-Light pattern. The problem was that I needed to implement two, seemingly similar pieces of functionality:

1. To copy any given cell in the data grid
2. To search the database, based on a specific piece of data in the selected row of the datagrid (regardless of which cell was selected).

To implement the Copy feature was unbelievably easy – you don’t even need a custom command; just add the following setting to the DataGrid:

SelectionUnit ="CellOrRowHeader"

And the following context menu:

<DataGrid.ContextMenu>
    <ContextMenu>                    
       <MenuItem Command="Copy"/>                    
    </ContextMenu>
</DataGrid.ContextMenu>

And the copy is done!

So, next, I wanted to implement the custom search. I needed to identify the currently selected row in my ViewModel, so I added a new property:

        private MyDataClass _selectedItem;
        public MyDataClass SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                _selectedItem = value;
                RaisePropertyChanged(() => SelectedItem);
            }
        }

I then bound this to the selected item of the datagrid, like this:

     < DataGrid ItemsSource ="{ Binding Path =MyDataCollection}"                   
                  SelectedItem="{ Binding Path =SelectedItem}"                   
                  SelectionUnit ="CellOrRowHeader"  
&#91;/sourcecode&#93;

And finally, created my command:

&#91;sourcecode language="csharp"&#93;
         public RelayCommand MyCommand { get ; private set ; }
&#91;/sourcecode&#93;

In the constructor, initialised it:

&#91;sourcecode language="csharp"&#93;
     this.MyCommand = new RelayCommand (() => this.MyCommandFunc());

Created the function:

         private void MyCommandFunc()
        {
            QueryDB(SelectedItem.ValueOne);
        }         

And, finally, setup the context menu:

<DataGrid.ContextMenu>
    <ContextMenu>                    
         <MenuItem Command ="Copy"/>                    
         <MenuItem Header ="My Funky Command" Command="{Binding MyCommand}"/>
    </ContextMenu>
</DataGrid.ContextMenu>

But this didn’t work! (Queue dramatic music).

The problem is down to this:

SelectionUnit ="CellOrRowHeader"

So, change it to:

SelectionUnit="FullRow" 

And it works again… but now copy doesn’t work, because it copies the FULL ROW!

So, the two features are incompatible?

I did find a workaround which doesn’t breach the separation of concerns. Please note that, although this does work, and does not breach separation of concerns, it may or may not be the best way of doing it. If you have, or know of, a better way the PLEASE leave a comment, or mail me and let me know.

The Workaround

Instead of binding the SelectedItem property, bind the Tag property of the grid:

< DataGrid ItemsSource ="{ Binding Path =MyDataCollection}" Tag="{ Binding Path =SelectedItem}" SelectionUnit ="CellOrRowHeader" [/sourcecode] Now, we need a little code-behind, which must remain agnostic to the ViewModel: [sourcecode language="csharp"] private void DataGrid_SelectedCellsChanged( object sender, SelectedCellsChangedEventArgs e) { (( DataGrid)sender).Tag = ((DataGrid)sender).SelectedCells.FirstOrDefault().Item; } [/sourcecode] Now, because the SelectedItem is bound in the view to the Tag, updating the Tag, updates the SelectedItem. This means that when you call your function (as described above): [sourcecode language="csharp"] private void MyCommandFunc() { QueryDB(SelectedItem.ValueOne); } [/sourcecode] SelectedItem is now set. Conclusion

Whilst I can see why this works the way it does, it doesn’t seem sensible that I need to jump through so many hoops to get this to work without breaking the separation of concern. It may just be a quirk with the DataGrid, but it feels like a hack – which I don’t like. Nevertheless, ATM it’s the only solution that I can come up with that doesn’t mean directly referencing the View from the ViewModel.

Implementing a call to search using MVVM Light

I recently started using the MVVM Light framework to create an app. One of the first things that I found tripped me up was trying to link the ViewModel functionality with the visual interface. After a little more searching than should be necessary I came across the concept of commands. Basically, thos allows you to bind the functionality of your view model to an action on the screen. In the example below it’s the action of clicking a button.

First, create a new relay command (this is in the namespace GalaSoft.MvvmLight.Command):

    public class MainViewModel : ViewModelBase
    {
        private readonly IDataService _dataService;

        /// <summary>
        /// The <see cref="WelcomeTitle" /> property's name.
        /// </summary>
        public const string WelcomeTitlePropertyName = "WelcomeTitle" ;

        private string _welcomeTitle = string.Empty;

               // New Command Variable
        public RelayCommand SearchCommand { get ; private set ; }
        ...

Next initialise the command in the constructor of the VM:

        public MainViewModel( IDataService dataService)
        {
            this.SearchCommand = new RelayCommand (this.GetDataCount);
            ...

Obviously, the execute function must exist. For example:

        private void GetData()
        {
                _dataservice.GetData((count, error) =>
                {
                    if (error != null)
                    {
                        // Report error here
                        return;
                    }

                    // Do something with data here
                });
        }

Finally, simply add a call from the XAML in MainWindow:

Parameters

You can also pass parameters, by simply providing the CommandParameter attribute and then using it. However, given that you’re already in the databound context (i.e. you’re function is in your ViewModel, which is bound to the DataContext) I didn’t find a need for this, as it’s possible to simply reference the property directly.

Conclusion

This ends up being quite a neat way to link the two. The screen is linked to the view model without having a chunk of code in the button click handler.