Click here to Skip to main content
13,765,143 members

.NET Framework

 
AnswerRe: Circle Progress in Visual Studio 2008 Pin
Gerry Schmitz8-Nov-17 5:01
memberGerry Schmitz8-Nov-17 5:01 
GeneralRe: Circle Progress in Visual Studio 2008 Pin
Member 135090598-Nov-17 14:48
memberMember 135090598-Nov-17 14:48 
QuestionCast issue with CaptureFileAsync() Pin
MA-Navinn26-Oct-17 3:54
memberMA-Navinn26-Oct-17 3:54 
AnswerRe: Cast issue with CaptureFileAsync() Pin
Richard MacCutchan26-Oct-17 4:30
protectorRichard MacCutchan26-Oct-17 4:30 
AnswerRe: Cast issue with CaptureFileAsync() Pin
Richard Deeming26-Oct-17 4:53
mvpRichard Deeming26-Oct-17 4:53 
GeneralRe: Cast issue with CaptureFileAsync() Pin
MA-Navinn27-Oct-17 7:00
memberMA-Navinn27-Oct-17 7:00 
GeneralRe: Cast issue with CaptureFileAsync() Pin
MA-Navinn7-Nov-17 23:59
memberMA-Navinn7-Nov-17 23:59 
QuestionProcess data as you type Pin
Dirk Bahle13-Oct-17 9:21
mvpDirk Bahle13-Oct-17 9:21 
I am trying to let a user type in a textbox and process input as the typing occurs - but also want to make sure that the last characters typed (when the user finished typing) are processed - I want to have only 1 processing task running at any time - so I would probably need something like the below with an async semaphore, right?

Does someone have a hint towards the correct code snippet?

MainWindow XAML:
<Window x:Class="InputTaskQueue.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        xmlns:behav="clr-namespace:InputTaskQueue.Behaviors"

        mc:Ignorable="d"

        Title="MainWindow" Height="350" Width="525">
    <StackPanel Orientation="Vertical">
        <TextBox Name="tbInput"

                 behav:TextChangedCommand.ChangedCommand="{Binding SearchCommand}"

                 HorizontalAlignment="Left" VerticalAlignment="Bottom"

                 Width="100" Height="20"/>

        <TextBlock Text="{Binding SearchStringResult,UpdateSourceTrigger=PropertyChanged,Mode=OneWay}" Width="100" Height="100" />
    </StackPanel>
</Window>

Text KeyUp Behavior Triggera command via binding:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

public static class TextChangedCommand
{
    // Field of attached ICommand property
    private static readonly DependencyProperty ChangedCommandProperty = DependencyProperty.RegisterAttached(
        "ChangedCommand",
        typeof(ICommand),
        typeof(TextChangedCommand),
        new PropertyMetadata(null, OnTextChangedCommandChange));

    public static void SetChangedCommand(DependencyObject source, ICommand value)
    {
        source.SetValue(ChangedCommandProperty, value);
    }

    public static ICommand GetChangedCommand(DependencyObject source)
    {
        return (ICommand)source.GetValue(ChangedCommandProperty);
    }

    private static void OnTextChangedCommandChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TextBox uiElement = d as TextBox;   // Remove the handler if it exist to avoid memory leaks

        if (uiElement != null)
        {
            uiElement.TextChanged -= OnText_Changed;

            var command = e.NewValue as ICommand;
            if (command != null)
            {
                // the property is attached so we attach the Drop event handler
                uiElement.TextChanged += OnText_Changed;
            }
        }
    }

    private static void OnText_Changed(object sender, TextChangedEventArgs e)
    {
        TextBox uiElement = sender as TextBox;

        // Sanity check just in case this was somehow send by something else
        if (uiElement == null)
            return;

        // Bugfix: A change during disabled state is likely to be caused by a bound property
        //         in a viewmodel (a machine based edit rather than user input)
        //         -> Lets break the message loop here to avoid unnecessary CPU processings...
        if (uiElement.IsEnabled == false)
            return;

        ICommand changedCommand = TextChangedCommand.GetChangedCommand(uiElement);

        // There may not be a command bound to this after all
        if (changedCommand == null)
            return;

        var item = uiElement.Text;

        // Check whether this attached behaviour is bound to a RoutedCommand
        if (changedCommand is RoutedCommand)
        {
            // Execute the routed command
            (changedCommand as RoutedCommand).Execute(item, uiElement);
        }
        else
        {
            // Execute the Command as bound delegate
            changedCommand.Execute(item);
        }
    }
}

ViewModel bond to MainWindow:
private string _SearchStrinResult;

/// <summary>
/// Gets a search string to match in the tree view.
/// </summary>
public string SearchStringResult
{
    get { return _SearchStrinResult; }
    private set
    {
        if (_SearchStrinResult != value)
        {
            _SearchStrinResult = value;
            NotifyPropertyChanged(() => SearchStringResult);
        }
    }
}
#endregion properties

#region methods
/// <summary>
/// Gets a command that filters the display of nodes in a treeview
/// with a filterstring (node is shown if filterstring is contained).
/// </summary>
public ICommand SearchCommand
{
    get
    {
        if (_SearchCommand == null)
        {
            _SearchCommand = new RelayCommand<object>((p) =>
            {
                string findThis = p as string;

                if (string.IsNullOrEmpty(findThis) == true)
                    return;

                SearchCommand_ExecutedAsync(findThis);
            },
            (p =>
            {
                return true;
            })
            );
        }

        return _SearchCommand;
    }
}

private List<string> _Queue = new List<string>();
private static SemaphoreSlim SlowStuffSemaphore = new SemaphoreSlim(1, 1);

private async void SearchCommand_ExecutedAsync(string input)
{
    _Queue.Add(input);

    // Issue 1: Not sure how to lock this with the correct semaphore信号
    //to make sure the task always processes the last input but is not started twice
    await SlowStuffSemaphore.WaitAsync();
    try
    {
        // There is more recent input to process so we ignore this one
        if (_Queue.Count > 1)
        {
            _Queue.Remove(input);
            return;
        }
        else
        {
            Console.WriteLine("Queue Count: {0}", _Queue.Count);
        }

        await createTask(input);

        _Queue.Remove(input);

        this.SearchStringResult = input;
    }
    catch (Exception exp)
    {
        Console.WriteLine(exp.Message);
    }
    finally
    {
        SlowStuffSemaphore.Release();
    }
}

private Task createTask(string input)
{
    return Task.Run(() =>
    {
        Console.WriteLine("searching:" + input);
        System.Threading.Thread.Sleep(5000);

    }) // simulate processing
    .ContinueWith((p) =>
    {
    });
}


modified 13-Oct-17 16:45pm.

AnswerRe: Process data as you type Pin
Eddy Vluggen13-Oct-17 23:39
professionalEddy Vluggen13-Oct-17 23:39 
GeneralRe: Process data as you type Pin
Dirk Bahle14-Oct-17 2:34
mvpDirk Bahle14-Oct-17 2:34 
GeneralRe: Process data as you type Pin
Eddy Vluggen14-Oct-17 3:40
professionalEddy Vluggen14-Oct-17 3:40 
GeneralRe: Process data as you type Pin
Dirk Bahle14-Oct-17 8:27
mvpDirk Bahle14-Oct-17 8:27 
GeneralRe: Process data as you type Pin
Eddy Vluggen17-Oct-17 3:06
professionalEddy Vluggen17-Oct-17 3:06 
AnswerRe: Process data as you type Pin
Gerry Schmitz14-Oct-17 9:35
memberGerry Schmitz14-Oct-17 9:35 
GeneralRe: Process data as you type Pin
Dirk Bahle16-Oct-17 4:15
mvpDirk Bahle16-Oct-17 4:15 
AnswerRe: Process data as you type Pin
Pete O'Hanlon14-Oct-17 12:47
protectorPete O'Hanlon14-Oct-17 12:47 
GeneralRe: Process data as you type Pin
Dirk Bahle16-Oct-17 4:19
mvpDirk Bahle16-Oct-17 4:19 
QuestionAn unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
indian1434-Oct-17 16:30
memberindian1434-Oct-17 16:30 
AnswerRe: An unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
Richard MacCutchan4-Oct-17 23:22
protectorRichard MacCutchan4-Oct-17 23:22 
GeneralRe: An unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
indian1435-Oct-17 4:08
memberindian1435-Oct-17 4:08 
GeneralRe: An unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
Richard MacCutchan5-Oct-17 4:14
protectorRichard MacCutchan5-Oct-17 4:14 
GeneralRe: An unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
indian1435-Oct-17 4:18
memberindian1435-Oct-17 4:18 
GeneralRe: An unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
Richard MacCutchan5-Oct-17 4:27
protectorRichard MacCutchan5-Oct-17 4:27 
GeneralRe: An unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
indian1435-Oct-17 4:34
memberindian1435-Oct-17 4:34 
GeneralRe: An unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
indian1435-Oct-17 8:46
memberindian1435-Oct-17 8:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.


Advertise | Privacy | Cookies | Terms of Service
Web01-2016 | 2.8.181114.1 | Last Updated 14 Nov 2018
Copyright © CodeProject, 1999-2018
All Rights Reserved.
Layout: fixed | fluid