Trying to separate 2 items in a column for listview wpf

348 views Asked by At

I am quite a newbie with wpf...any help will be appreciated. I started a small project with a listview that displays content from MySQL. So far I had no problems except a column that has 2 items in it. I need to separate each item in its own column. It was easy to do with date and time but this one is beyond my skills.

The display of the listview is like that (I can't post images yet):

Date |Time |CallerID |From|To |Duration

10 June 2015 |22:45|"alex" <210555555>|101 |201|234

The CallerID column contains the two values with distinct "" and <>. I need to separate as I did with Date and Time. Thanks for any help.

  <ListView x:Name="Datalist" Grid.Column="1" Grid.Row="4" 
ItemsSource="{Binding Path=DS}" Background="White" Foreground="Black" FontSize="16" Grid.ColumnSpan="4" FontFamily="Segoe UI" Margin="1,0,8,0">
        <ListView.View>
            <GridView AllowsColumnReorder="False">
                <GridViewColumn Header="Date" DisplayMemberBinding="{Binding Path=calldate,StringFormat={}{0:dd MMMM yyyy}}"/>
                <GridViewColumn Header="Time" DisplayMemberBinding="{Binding Path=calldate,StringFormat={}{0:HH:mm:ss}}"/>
                <GridViewColumn Header="CallerID" DisplayMemberBinding="{Binding Path=clid}"/>
                <GridViewColumn Header="From" DisplayMemberBinding="{Binding Path=src}"/>
                <GridViewColumn Header="To" DisplayMemberBinding="{Binding Path=dst}"/>
                <GridViewColumn Header="Duration"  DisplayMemberBinding="{Binding duration}" />
            </GridView>
        </ListView.View>
    </ListView>

private void OnLoad(object sender, RoutedEventArgs e)
        {
        string cs = @"server=192.168.1.123;userid=alex;
        password=r3s3ll3r;database=asteriskcdrdb";

        MySqlConnection conn = null;
        MySqlDataReader rdr = null;

        try
            {
            conn = new MySqlConnection(cs);
            conn.Open();

            string stm = "(SELECT * FROM cdr ORDER BY uniqueid DESC LIMIT 1000)";
            mySqlDataAdapter = new MySqlDataAdapter(stm, cs);
            mySqlDataAdapter.Fill(DS);
            Datalist.ItemsSource = DS.DefaultView;

            }
        catch (MySqlException ex)
            {
            MessageBox.Show("Error: {0}", ex.ToString());

            }
        finally
            {
            if (rdr != null)
                {
                rdr.Close();
                }

            if (conn != null)
                {
                conn.Close();
                }

            }
        }
3

There are 3 answers

1
Michael On

Consider moving towards a more complete view model approach. Instead of binding your ItemsSource to the DataTable.DefaultView directly, you could create a collection of view models that define the presentation logic for each entry. For example, you could define a view model class such as

public class PhoneCallViewModel
{
  public Date CallDate { get; set; }
  public string CallerId { get; set; }
  // .... Expose properties for each column
}

This will open up a lot of options for dealing with your current problem. For example, how could we split up that caller ID string? You could create another view model, such as the following

public class CallerIDViewModel
{
  public string CallerName { get; set; }
  public string CallerNumber { get; set; }
}

Then the PhoneCallViewModel would expose a CallerIDViewModel property. In your OnLoad method, you would create a collection of these PhoneCallViewModel objects (preferably an ObservableCollection) and bind the ItemsSource to it. Then you could simply replace your existing caller id column in your ListView with two new columns. One bound to CallerID.CallerName, and the second bound to CallerID.CallerNumber (assuming the property on PhoneCallViewModel is named CallerID).

I've left out the details of splitting the original caller ID as well as instantiating the collection, as those are separate implementation problems.

1
Maxime Tremblay-Savard On

You could always create a converter and pass your clid to it with a parameter saying if you want the name of the number and it would return you the right one.

It would look like:

<GridViewColumn Header="CallerID" DisplayMemberBinding="{Binding Path=clid, Converter={StaticResource GetCallerIdConverter}, ConverterParameter='Name'}"/>

and then the converter:

public class GetCallerIdConverter : IValueConverter {

public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) {
  string callerId = value.toString();
  if (parameter == "Name")
  {
    //your regex to return what's in the double quotes ""
  }
  else
  {
    //your regex to return what's in the < >
  }
}
0
Alex On
Thank you all for the help, this is a great community!
So, i used a converter as maxime-tremblay-savard suggested.



      class GetCalleridConverter : IValueConverter
            {
                    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
                {
                string callerId = (string)value;
                Regex angleBrackets = new Regex("<[^(>)]*>");
                Regex quotes = new Regex("\"([^\"]*)\"");
                if (parameter.ToString() == "Number")
                    {
                    //your regex to return what's in the double quotes ""

                    Match angled = angleBrackets.Match(callerId);
                    return angled.ToString();
                    }
                else  
                    {
                    Match quot = quotes.Match(callerId);
                    return quot.ToString();
                    }


                }

//And then i binded the item to xaml

.....
  <Page.Resources>
        <valueconverter:GetCalleridConverter x:Key="GetCallerIdConverter" />
    </Page.Resources>
.......
 <GridViewColumn Header="Caller Name" Width="auto" DisplayMemberBinding="{Binding Path=clid, Converter={StaticResource GetCallerIdConverter}, ConverterParameter='Name'}"/>
                    <GridViewColumn Header="Caller Number" Width="auto" DisplayMemberBinding="{Binding Path=clid, Converter={StaticResource GetCallerIdConverter}, ConverterParameter='Number'}"/>

//So, i got two columns with caller Name and Caller Number, only thing left to remove quotes and angle brackets....

enter image description here