listview dblclick - what column?

M

mp

Hi
given listview with gridview with 3 columns...trying to find which item was
dbl clicked on
I can get the row a double click event occured (.SelectedItem) in but can't
find how to get which column of that row was clicked in
I saw a property like point location of mouse(forget the exact name)...do i
have to use a location like that and compute from column widths etc to find
which column? surely not!
any hints where to look in docs to find this?
thanks mark
 
M

mp

mp said:
Hi
given listview with gridview with 3 columns...trying to find which item
was dbl clicked on
I can get the row a double click event occured (.SelectedItem) in but
can't find how to get which column of that row was clicked in
I saw a property like point location of mouse(forget the exact name)...do
i have to use a location like that and compute from column widths etc to
find which column? surely not!
any hints where to look in docs to find this?
thanks mark

ps this is in wpf project...forgot to mention...if it matters...
have looked through hundreds of google posts on listview and it appears i
may have to use the mouse position after all?
can't find an exposed property of listview.columns or listview.grid.columns
or anything to read at runtime the widths of the columns
I can hard code the values to test against mouse position.x based on the
defined widths in the xaml defined grid columns but that seems like a bad
approach...but so far all i can find that works
any other tips appreciated
thanks
mark
 
M

mp

mp said:
mp said:
Hi
given listview with gridview with 3 columns...trying to find which item
was dbl clicked on
[]
ps this is in wpf project...forgot to mention...if it matters...
have looked through hundreds of google posts on listview and it appears i
may have to use the mouse position after all?
can't find an exposed property of listview.columns or
listview.grid.columns or anything to read at runtime the widths of the
columns
I can hard code the values to test against mouse position.x based on the
defined widths in the xaml defined grid columns but that seems like a bad
approach...but so far all i can find that works
any other tips appreciated
thanks
mark

this works unless i change column widths at runtime which is why it would be
nice to be able to read column width values programatically
private void Listview1_MouseDoubleClick(object sender, MouseButtonEventArgs
e)

{Point position = Mouse.GetPosition(Listview1 );


if (position.X < 150)

MessageBox.Show("Col 1");

else if (position.X < 450)

MessageBox.Show("Col 2");

else

MessageBox.Show("Col 3");
 
M

mp

ok finally figured it out
private void Listview1_MouseDoubleClick(object sender, MouseButtonEventArgs
e)

{

Point position = Mouse.GetPosition(Listview1 );

GridView gv = Listview1.View as GridView;

if (position.X < gv.Columns[0].Width)

MessageBox.Show("Col 1");

else if (position.X < gv.Columns[0].Width + gv.Columns[1].Width)

MessageBox.Show("Col 2");

else

MessageBox.Show("Col 3");
 
M

mp

given listview with gridview with 3 columns...trying to find which item
was dbl clicked on
[...]
this is in wpf project
[...]
ok apparently i'm the only one with this problem or interest but for the
sake of posterity<g>
in case any beginner is looking for this in the future, the way i found that
works is as follows:
(i don't know if theres' a better way to do this but this is what I finally
came up with)
(obviously it could be generalized with a column index variable in a loop to
deal with any number of columns)
private void Listview1_MouseDoubleClick(object sender, MouseButtonEventArgs
e)

{

Point position = Mouse.GetPosition(Listview1 );

GridView gv = Listview1.View as GridView;

//this allows runtime evaluation of column widths

if (position.X < gv.Columns[0].Width)

MessageBox.Show("Col 1");

else if (position.X < gv.Columns[0].Width + gv.Columns[1].Width)

MessageBox.Show("Col 2");

else

MessageBox.Show("Col 3");

}
 
M

mp

mp said:
given listview with gridview with 3 columns...trying to find which item
was dbl clicked on [...]
this is in wpf project
[...]
ok apparently i'm the only one with this problem or interest but for the
sake of posterity<g>
[...]
oops didn't realize i'd already posted that yesterday...
anyhow if the headers get rearranged at runtime by user i have to track the
header.ToString to keep synced with which column is which
private void Listview1_MouseDoubleClick(object sender, MouseButtonEventArgs
e)

{Point position = Mouse.GetPosition(ListView1 );

//FunctionInfo is custom object to which listview was bound via xaml

FunctionInfo fi = (FunctionInfo)ListView1.SelectedItem;


GridView gv = ListView1.View as GridView;





int CurrentColumnPosition=0;

for (int columnNumber = 0; columnNumber < gv.Columns.Count; columnNumber++)

{CurrentColumnPosition = CurrentColumnPosition +
(int)gv.Columns[columnNumber].Width;

if (position.X < CurrentColumnPosition)

//if i had more than 3 choices i'd want to figure a way to generalize this?
enums? some object that knows about the choices? other??

{if (gv.Columns[columnNumber].Header.ToString() == "Function")

{Debug.Print(fi.Name);

break;}

else if (gv.Columns[columnNumber].Header.ToString() == "Signature")

{Debug.Print(fi.Signature);

break;}

else if (gv.Columns[columnNumber].Header.ToString() == "Filename")

{Debug.Print(fi.FileName);

break;}

else

Debug.Print("no header match???");}}



i only keep posting this conversation with myself in the hopes someone will
chime in and show me where it can be improved.

thanks

mark
 
P

Peter Duniho

[...]
i only keep posting this conversation with myself in the hopes someone
will
chime in and show me where it can be improved.

On the WPF-specific points (such as the best way to identify the
double-clicked column), you may find this forum limited in expertise.
Some of the .NET GUI controls have built-in functions for mapping mouse
coordinates to specific elements of the control. Not being that familiar
with the WPF controls, I don't know if that's present for your GridView,
but it might be.

As far as the mapping from column number to FunctionInfo property goes, a
common approach for that scenario is to use a dictionary rather than
specifically-named properties. That way, you can always retrieve the
property by name directly.

Alternatively, arguably you shouldn't be accessing the properties by name
anyway, since the name you're getting is from the UI, which should have
little or nothing to do with the names of things in code. Instead, have a
way of mapping directly from the column number or the column object
itself; for example, maintain an array that is parallel to the column
order, or do a "decoration" of sorts by creating a dictionary mapping the
GridViewColumn object itself to the necessary information, rather than its
string.

Either way, that allows you to manipulate the text displayed to the user
without that affecting the underlying code.

As far as what the mapping from the column goes to, that can be the name
of the property or an enum, or some other way of identifying the
property. To get from that to a property, the simplest approach would be
to just use a "switch" statement.

So, taking all that together, you might get something that looks a little
like this:

Initialized somewhere for the class:

string[] rgstrProperties = { "Name", "Signature", "Filename" };

Then, after calculating "columnNumber":

switch (rgstrProperties[columnNumber])
{
case "Name":
Debug.Print(fi.Name);
break;
case "Signature":
Debug.Print(fi.Signature);
break;
case "Filename":
Debug.Print(fi.Filename);
break;
}

Of course, the above is most useful if you anticipate having to rearrange
the columns. Then you only have to change the string[] with the names,
rather than all the rest of the code that maps the columns to the
properties.

But if you want, you can skip the string[] altogether and just embed the
mapping in your switch statement:

switch (columnNumber)
{
case 0:
Debug.Print(fi.Name);
break;
case 1:
Debug.Print(fi.Signature);
break;
case 2:
Debug.Print(fi.Filename);
break;
}

Pete
 
M

mp

Peter Duniho said:
[...]
i only keep posting this conversation with myself in the hopes someone
will
chime in and show me where it can be improved.

On the WPF-specific points (such as the best way to identify the
double-clicked column), you may find this forum limited in expertise.
Some of the .NET GUI controls have built-in functions for mapping mouse
coordinates to specific elements of the control. Not being that familiar
with the WPF controls, I don't know if that's present for your GridView,
but it might be.

Hi Pete,
apparently the gridview and gridviewcolumn objects expose no
events(according to properties window)
As far as the mapping from column number to FunctionInfo property goes, a
common approach for that scenario is to use a dictionary rather than
specifically-named properties. That way, you can always retrieve the
property by name directly.

sorry, not quite following that...
actually i started with a SortedDictionary containing my 3 values
i loop through that creating the Info objects to hold the 3 values in order
to use object binding to fill the listview.
(this is just a test app to learn c# for me, so i was mostly practicing
binding)
each col shows one property
the idea was dblclick on column would report that property (in a real app
something more useful might happen :) )
it is simple until i rearrange the columns...that's where i'm trying to find
a
the preferred way to follow those moving targets.
Alternatively, arguably you shouldn't be accessing the properties by name
anyway, since the name you're getting is from the UI, which should have
little or nothing to do with the names of things in code.

the only reason i used the header.toString is i couldn't find any other way
to track the columns once they are rearranged by dragging headers at
runtime, so i can't use their index as that will change when they're moved.
the headers just happen to match(almost) the property names as that's what
the listview was displaying.

Instead, have a
way of mapping directly from the column number or the column object
itself; for example, maintain an array that is parallel to the column
order, or do a "decoration" of sorts by creating a dictionary mapping the
GridViewColumn object itself to the necessary information, rather than its
string.

if i could find a way to get a reference to a column object that would
follow it as it moved in index order that would be simpler...i just don't
see a way to get
Either way, that allows you to manipulate the text displayed to the user
without that affecting the underlying code.

As far as what the mapping from the column goes to, that can be the name
of the property or an enum, or some other way of identifying the
property. To get from that to a property, the simplest approach would be
to just use a "switch" statement.

So, taking all that together, you might get something that looks a little
like this:

Initialized somewhere for the class:

string[] rgstrProperties = { "Name", "Signature", "Filename" };

Then, after calculating "columnNumber":

switch (rgstrProperties[columnNumber])
{
case "Name":
Debug.Print(fi.Name);
break;
case "Signature":
Debug.Print(fi.Signature);
break;
case "Filename":
Debug.Print(fi.Filename);
break;
}

Of course, the above is most useful if you anticipate having to rearrange
the columns. Then you only have to change the string[] with the names,
rather than all the rest of the code that maps the columns to the
properties.

sounds good but i'd have to be able to catch a headersRearranged event...if
there were such an animal...havent' found it yet though that doesn't mean
it's not there...<g>

then when the cols rearrange i'd have to rearrange the title array
accordingly...
not sure if thats cleaner or easier than just tracking the header values as
they do stay with the col as it's moved...
granted it's not a good example of decoupling ui from code logic but i'm not
seeing how i can divorce the two
But if you want, you can skip the string[] altogether and just embed the
mapping in your switch statement:

that's what i tried at first when i realized the cols could be rearranged by
user at runtime so then the hardcoded col number fails to track the moving
colunms...
switch (columnNumber)
{
case 0:
Debug.Print(fi.Name);
break;
case 1:
Debug.Print(fi.Signature);
break;
case 2:
Debug.Print(fi.Filename);
break;
}

Pete

much appreciate the thoughts and ideas...will meditate on this for a while
and see if an aha! moment emerges!<g>
thanks
mark
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top