Click here to Skip to main content
15,884,237 members
Home / Discussions / .NET (Core and Framework)
   

.NET (Core and Framework)

 
AnswerRe: Circle Progress in Visual Studio 2008 Pin
Gerry Schmitz8-Nov-17 4:01
mveGerry Schmitz8-Nov-17 4:01 
GeneralRe: Circle Progress in Visual Studio 2008 Pin
Member 135090598-Nov-17 13:48
Member 135090598-Nov-17 13:48 
QuestionCast issue with CaptureFileAsync() Pin
MA-Navinn26-Oct-17 2:54
MA-Navinn26-Oct-17 2:54 
AnswerRe: Cast issue with CaptureFileAsync() Pin
Richard MacCutchan26-Oct-17 3:30
mveRichard MacCutchan26-Oct-17 3:30 
AnswerRe: Cast issue with CaptureFileAsync() Pin
Richard Deeming26-Oct-17 3:53
mveRichard Deeming26-Oct-17 3:53 
GeneralRe: Cast issue with CaptureFileAsync() Pin
MA-Navinn27-Oct-17 6:00
MA-Navinn27-Oct-17 6:00 
GeneralRe: Cast issue with CaptureFileAsync() Pin
MA-Navinn7-Nov-17 22:59
MA-Navinn7-Nov-17 22:59 
QuestionProcess data as you type Pin
Dirk Bahle13-Oct-17 8:21
Dirk Bahle13-Oct-17 8: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:
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:
C#
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:
C#
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 22:39
professionalEddy Vluggen13-Oct-17 22:39 
GeneralRe: Process data as you type Pin
Dirk Bahle14-Oct-17 1:34
Dirk Bahle14-Oct-17 1:34 
GeneralRe: Process data as you type Pin
Eddy Vluggen14-Oct-17 2:40
professionalEddy Vluggen14-Oct-17 2:40 
GeneralRe: Process data as you type Pin
Dirk Bahle14-Oct-17 7:27
Dirk Bahle14-Oct-17 7:27 
GeneralRe: Process data as you type Pin
Eddy Vluggen17-Oct-17 2:06
professionalEddy Vluggen17-Oct-17 2:06 
AnswerRe: Process data as you type Pin
Gerry Schmitz14-Oct-17 8:35
mveGerry Schmitz14-Oct-17 8:35 
GeneralRe: Process data as you type Pin
Dirk Bahle16-Oct-17 3:15
Dirk Bahle16-Oct-17 3:15 
AnswerRe: Process data as you type Pin
Pete O'Hanlon14-Oct-17 11:47
mvePete O'Hanlon14-Oct-17 11:47 
GeneralRe: Process data as you type Pin
Dirk Bahle16-Oct-17 3:19
Dirk Bahle16-Oct-17 3:19 
QuestionAn unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
indian1434-Oct-17 15:30
indian1434-Oct-17 15:30 
AnswerRe: An unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
Richard MacCutchan4-Oct-17 22:22
mveRichard MacCutchan4-Oct-17 22:22 
GeneralRe: An unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
indian1435-Oct-17 3:08
indian1435-Oct-17 3:08 
GeneralRe: An unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
Richard MacCutchan5-Oct-17 3:14
mveRichard MacCutchan5-Oct-17 3:14 
GeneralRe: An unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
indian1435-Oct-17 3:18
indian1435-Oct-17 3:18 
GeneralRe: An unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
Richard MacCutchan5-Oct-17 3:27
mveRichard MacCutchan5-Oct-17 3:27 
GeneralRe: An unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
indian1435-Oct-17 3:34
indian1435-Oct-17 3:34 
GeneralRe: An unhandled exception of type 'System.AccessViolationException' occurred in System.Data.dll Pin
indian1435-Oct-17 7:46
indian1435-Oct-17 7: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.