Is there a way to tell if the window was resized by user or programatically?
Short question
I would like to handle SizeChange event base on the real cause of the resizing -- (1) due to interaction by user or (2) something else. How can I tell the difference?
Background (short)
I have window with datagrid inside, the window is supposed to fit to its content. To achieve this I have to set all columns width to Auto. But then, when the user resize the window by hand, additional "virtual" columns appears -- this is ugly. So my solution would be this -- settings the width to Auto for columns, but as soon the user resizes the window, t开发者_如何学Che last column of datagrid is switched to "*".
But to do this, I have to read the cause of resizing.
More details (edit 1)
For now (!) the first thing is window is resized internally because it is created. Then it is resized again, because the position and size is restored from the disk (this is my code). Then it is resized again, because the data are loaded into datagrid. Those resizing are all causes by non-interaction by user. So all columns width should be = Auto.
On first user (!) resizing it should be switched to "Star" mode, i.e. "*".
More details (edit 2)
It appears, that many people don't realize the issue here. You can set the width of the last column to Auto or "*" (width of all other columns are Auto). But because I use SizeToContent, only Auto makes sense. Initially.
Now, several people think the answer is reacting to every resize event. This means I would set the width to "*" immediately. But why I would set Width to "*" in the event, when I could set it directly in XAML?
In case somebody still does not get here is the workflow of intended behaviour (let's say I have 3 columns):
- Widths = Auto, Auto, Auto
- Window is created, resize occurs
- Widths = Auto, Auto, Auto
- Window size is restored, resize occurs
- Widths = Auto, Auto, Auto
- Data are loaded, resize occurs
- Widths = Auto, Auto, Auto
- User resizes the window manually, resize occurs
- Widths = Auto, Auto, "*" (!)
Please note, in every steps window looks good, user interaction is "optional" of course.
Now, compare it to the suggested "solution".
- Widths = Auto, Auto, Auto
- Window is created, resize occurs
- Widths = Auto, Auto, "*" (from this point, window looks ugly)
- Window size is restored, resize occurs
- Widths = Auto, Auto, "*"
- Data are loaded, resize occurs
- Widths = Auto, Auto, "*"
- User resizes the window manually, resize occurs
- Widths = Auto, Auto, "*" (looks OK, since it is user will)
This "solution" is 100% equivalent to this:
- Widths = Auto, Auto, "*"
- Window is created
- Window size is restored
- Data are loaded
- User resizes the window manually
I no longer care about resizing, the code is simpler, the only disadvantage is the window looks ugly. Well, the fact is, it is actually a deal breaker.
Please post your answers as answers, I already have 2 comments which solved my problems, and I cannot mark them, because they are comments. Thank you in advance.
If your window is initially set to SizeToContent="WidthAndHeight"
(or "Width"
), then you can bind to this property and detect when it changes to "Manual"
, indicating that a user resize action has commenced. When it switches to "Manual"
, you can activate bindings or events that react to any further resizing. The value of SizeToContent
is updated as soon as the user clicks (mouse button down) on the border of the window, i.e., before any actual resizing has taken place.
Judging by the comments, many people did not understand the point of the question. There are two very distinct situations involving change of window size:
- The contents of the window changes (which could be due to any number of reasons), and the window size is changed to fit the contents. Since the change in windows size is done precisely to fit the contents, there is no need to subsequently change the size of the contents.
- The user changes the window size. In this case the new size of the window will not match the size of the contents, and the size of the contents should thus be adjusted to fill the new window size.
Of course, as suggested in some comments, it's possible that the window cannot become large enough to accommodate the contents due to other limits (which can be handled by adding a ScrollViewer
control with "Auto"
visibilities), but for many applications, the only situation where the window becomes larger than the contents require is if the user resizes the window manually.
I have used this method myself to make limits to the possible auto-height or -width of the window that are disabled when the user resizes the window manually - in my application, there are windows that should not automatically dominate the screen (but should otherwise adapt to the contents), but if the user wants to expand a window, they should be free to do so.
generally speaking, the only thing that resizes the window besides the user is your application. Though it is possible in the Windows sdk to change the size of a window you have the handle to, (like Cody) I don't understand why the same logic isn't applicable.
however, I'd recommend a different approach, maybe a Multi-Value converter.
taking in the original/desired column width (ocw), the original screen size (oss), and current screen size (css) then the column width should be (css x ocw)/oss, and will be automatically updated when the window size changes.
精彩评论