0

I'm working on a SignalR WPF application. Im sending messages from Windows Phone. I want to find specific item in that collection.

My view model:

 public ViewModel()
    {
        Messages = new ObservableCollection<string>();

        _connection = new HubConnection("http://localhost:49671/");
        _dataHub = _connection.CreateHubProxy("dataHub");
    }

    public ObservableCollection<string> Messages
    {
        get { return _messages; }
        set
        {
            if (Equals(value, _messages)) return;
            _messages = value;
            OnPropertyChanged("Messages");
        }
    }
    public async Task Login(string roomName, string userName)
    {
        _userName = userName;
        _roomName = roomName;

        await _connection.Start();
        await _dataHub.Invoke("JoinRoom", new object[] { _roomName, _userName });
        _dataHub.Subscribe("ReceiveMessage").Received += list =>
         Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() =>
         Messages.Add(list[0].ToString())));
    }

Codes that I tried to search

var asd2 = App.MainViewModel.Messages.Where(a => a.Contains("on"));
var on = App.MainViewModel.Messages.IndexOf(App.MainViewModel.Messages.Where(x => x == "on").FirstOrDefault());
List<string> asd = App.MainViewModel.Messages.Where(a => a.Contains("on")).ToList();
var q = App.MainViewModel.Messages.IndexOf(App.MainViewModel.Messages.Contains("on").ToString());

nothing worked for now. Please help .

Edit: The answer on this site didnt work for me. I dont know where the problem is

Pragmateek
  • 13,174
  • 9
  • 74
  • 108
  • Could it be something as trivial as casing? Did you try to ignore case? var res = App.MainViewModel.Messages.Where(a => a.IndexOf("on", StringComparison.CurrentCultureIgnoreCase) >= 0); – sondergard Aug 28 '14 at 20:43
  • I didnt understand that code much. Is this the right way to use if statement for my operations ?code : if ( res != null) { // my code } – Mustafa Özgüner Aug 28 '14 at 20:51
  • Btw - what do you actually mean "nothing worked"? What result are getting, and what do you need? – sondergard Aug 28 '14 at 21:29
  • 1
    @MustafaÖzgüner Have you checked that the list contains anything? Have you tried .Invoke(...) ? – Stígandr Aug 28 '14 at 21:30

3 Answers3

1

Attempt no 1 should work fine, as long as the target string has the same casing (UPPERCASE vs lowercase). This search is case sensitive meaning it will NOT find "On", "oN" or "ON" bacause they have different casings. To make case insensitive search, you can use IndexOf instead, which takes a StringComparison parameter:

var asd2 = App.MainViewModel.Messages.Where(a => a.IndexOf("on", StringComparison.CurrentCultureIgnoreCase) >= 0);

Attempt no 2 finds the start position of the first string which matches "on" (again - case sensitive)... This doesn't make any sense really, since any string which exactly matches "on", will always start a position 0.

Attempt no 3 does the same as attempt no 1, but converts the result to a list (Where returns IEnumerable)

Attempt no 4 essentially tries to find the starting position of either "true" or "false". The Contains method will return true if the string "on" (again only exact match) is found, and that result is converted to a string and passed to the IndexOf.

UPDATE

Where returns an IEnumerable (with all the matches found). If you only need to check if "on" exists, you can use Any:

bool containsOn = App.MainViewModel.Messages.Any(a => a.IndexOf("on", StringComparison.CurrentCultureIgnoreCase) >= 0);
sondergard
  • 3,184
  • 1
  • 16
  • 25
  • Im sending "on" and "off" messages by clicking buttons. And i want my wpf app to recognize these messages. Nothing worked so far. Should i change my view models ? – Mustafa Özgüner Aug 28 '14 at 21:16
  • If you are certain the you are putting "on"/"off" into Messages, the problem must be elsewhere. Using the first attempt should work. Can you provide more context and code? – sondergard Aug 28 '14 at 21:21
  • I found my mistake I changed my code with this _dataHub.Subscribe("ReceiveMessage").Received += list => Messages.Add(list[0].ToString()); and added this and list comes with some 1 object. But i dont know how to use if statement List asd = App.MainViewModel.Messages.Where(a => a.Contains("on")).ToList() – Mustafa Özgüner Aug 28 '14 at 21:38
  • 1
    .Where returns IEnumerable, and it will be empty if "on" is not found, so you could write if (!asd.Any()). Alternatively you can use .Any on the list directly instead of .Where (see my update) – sondergard Aug 28 '14 at 21:41
0

If you are dealing with cases and don't have an async issue, the code below works.

Check out this post

Extension method, taken from the post basicly.

public static class StringExt
{
    public static bool Contains(this string source, string toCheck, StringComparison comp)
    {
        return source.IndexOf(toCheck, comp) >= 0;
    }
}

Note that the extension method above will find everything with "on" in it regardless of case, add or modify methods to suit your needs, makes life easier :) I personally love them!

Then for searching

// get first message with on in it
var res = App.MainViewModel.Messages.FirstOrDefault(m => m.Contains("on", StringComparison.OrdinalIgnoreCase));
// get everything with on in it
var res2 = App.MainViewModel.Messages.Where(m => m.Contains("on", StringComparison.OrdinalIgnoreCase));

Hope it helps, and was what you were after

Cheers

Stian

Community
  • 1
  • 1
Stígandr
  • 2,874
  • 21
  • 36
  • both of your codes giving errors saying 'string' does not contain a definition for 'Contains' – Mustafa Özgüner Aug 28 '14 at 21:19
  • @MustafaÖzgüner you must add the static class with the [extension method](http://msdn.microsoft.com/en-us//library/bb383977.aspx) in your namespace, for making it work. What it does is adding a new method to the existing string class, quite handy. – Stígandr Aug 28 '14 at 21:20
0

Sending messages as strings like this is really not ideal. Maybe have a look at this library that uses the Event aggregation pattern?

Disclaimer: I'm the author

https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/wiki

Anders
  • 17,306
  • 10
  • 76
  • 144