We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Open_File_Dialog crashes on W10 with custom file_type
following code:
```
fname = self.main_window.open_file_dialog(
  title="Open RTF file",
  multiselect=False,
  file_types=['rtf']
)
```

## Expected Behavior
should work fine ond every platform

## Current Behavior
works fine on linux, crashes on Windows 10:
```
Traceback (most recent call last):
  File "C:\Users\user\AppData\Local\Programs\NewGAN Manager\\app\newganmanager\app.py", line 301, in action_open_file_dialog
    file_types=['rtf']
  File "C:\Users\user\AppData\Local\Programs\NewGAN Manager\\app_packages\toga\window.py", line 282, in open_file_dialog
    return self._impl.open_file_dialog(title, initial_directory, file_types, multiselect)
  File "C:\Users\user\AppData\Local\Programs\NewGAN Manager\\app_packages\toga_winforms\window.py", line 182, in open_file_dialog
    "|All files (*.*)|*.*"
System.ArgumentException: Die angegebene Filterzeichenfolge ist ungültig. Sie muss eine Beschreibung des Filters gefolgt von einem vertikalen Strich (|) und dem Filtermuster enthalten. Die Zeichenfolgen für andere Filteroptionen müssen ebenfalls durch einen vertikalen Strich getrennt werden. Beispiel: "Textdateien (*.txt)|*.txt|Alle Dateien (*.*)|*.*".
   bei System.Windows.Forms.FileDialog.set_Filter(String value)
```
Translated: The provided filter-string is invalid. It must consist of a description of the filter a vertical bar (|) and the filter-pattern. Following the example of the FIXME

## Steps to reproduce
see snippet.

* Python Version (list the specific version number)
python 3.7

* Operating System and Version (select from the following and list the specific version number; if your OS is not listed, list that as well)

  - [x] Windows - version: 10


* Toga Version (list the specific version number or git hash)

* Toga Target (the type of app you are trying to generate)

  - [ ] android
  - [ ] cocoa
  - [ ] django
  - [x] gtk
  - [ ] iOS
  - [ ] tvOS
  - [ ] watchOS
  - [x] winforms
  - [ ] win32
  - [ ] Other (please specify)

## Proposed Solution
change https://github.com/beeware/toga/blob/master/src/winforms/toga_winforms/window.py#L181
to
```
file_string = "{0} files (*.{0})|*.{0}"
fil = '|'.join([file_string.format(ext) for ext in file_types]) + \
                            "|All files (*.*)|*.*"

```
This is ofc not an ideal solution, because we just add a generic description, but since there is no wrapper for an appropriate datatype I feel this would be a reasonable bridging solution.

src: https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.filedialog.filter?view=netcore-3.1

P.S: I can't contribute to windows myself, because I barely get my hands on a W10 machine and I just had a few minutes to test it out. Cheers

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/winforms/toga_winforms/window.py`
Content:
```
1 from toga import GROUP_BREAK, SECTION_BREAK
2 
3 from .libs import WinForms, Size
4 
5 
6 class WinFormsViewport:
7     def __init__(self, native, frame):
8         self.native = native
9         self.frame = frame
10         self.baseline_dpi = 96
11 
12     @property
13     def width(self):
14         # Treat `native=None` as a 0x0 viewport
15         if self.native is None:
16             return 0
17         return self.native.ClientSize.Width
18 
19     @property
20     def height(self):
21         if self.native is None:
22             return 0
23         # Subtract any vertical shift of the frame. This is to allow
24         # for toolbars, or any other viewport-level decoration.
25         return self.native.ClientSize.Height - self.frame.vertical_shift
26 
27     @property
28     def dpi(self):
29         if self.native is None:
30             return self.baseline_dpi
31         return self.native.CreateGraphics().DpiX
32 
33 
34 class Window:
35     def __init__(self, interface):
36         self.interface = interface
37         self.interface._impl = self
38         self.create()
39 
40     def create(self):
41         self.native = WinForms.Form(self)
42         self.native.ClientSize = Size(*self.interface._size)
43         self.native.interface = self.interface
44         self.native.Resize += self.winforms_resize
45         self.toolbar_native = None
46         self.toolbar_items = None
47 
48     def create_toolbar(self):
49         self.toolbar_native = WinForms.ToolStrip()
50         for cmd in self.interface.toolbar:
51             if cmd == GROUP_BREAK:
52                 item = WinForms.ToolStripSeparator()
53             elif cmd == SECTION_BREAK:
54                 item = WinForms.ToolStripSeparator()
55             else:
56                 if cmd.icon is not None:
57                     native_icon = cmd.icon._impl.native
58                     item = WinForms.ToolStripMenuItem(cmd.label, native_icon.ToBitmap())
59                 else:
60                     item = WinForms.ToolStripMenuItem(cmd.label)
61                 item.Click += cmd._impl.as_handler()
62                 cmd._impl.native.append(item)
63             self.toolbar_native.Items.Add(item)
64 
65     def set_position(self, position):
66         pass
67 
68     def set_size(self, size):
69         self.native.ClientSize = Size(*self.interface._size)
70 
71     def set_app(self, app):
72         pass
73 
74     @property
75     def vertical_shift(self):
76         # vertical shift is the toolbar height or 0
77         result = 0
78         try:
79             result += self.native.interface._impl.toolbar_native.Height
80         except AttributeError:
81             pass
82         try:
83             result += self.native.interface._impl.native.MainMenuStrip.Height
84         except AttributeError:
85             pass
86         return result
87 
88     def set_content(self, widget):
89         if self.toolbar_native:
90             self.native.Controls.Add(self.toolbar_native)
91             # Create the lookup table of menu items,
92             # then force the creation of the menus.
93         self.native.Controls.Add(widget.native)
94 
95         # Set the widget's viewport to be based on the window's content.
96         widget.viewport = WinFormsViewport(native=self.native, frame=self)
97         widget.frame = self
98 
99         # Add all children to the content widget.
100         for child in widget.interface.children:
101             child._impl.container = widget
102 
103     def set_title(self, title):
104         self.native.Text = title
105 
106     def show(self):
107         # The first render of the content will establish the
108         # minimum possible content size; use that to enforce
109         # a minimum window size.
110         TITLEBAR_HEIGHT = WinForms.SystemInformation.CaptionHeight
111         # Now that the content is visible, we can do our initial hinting,
112         # and use that as the basis for setting the minimum window size.
113         self.interface.content._impl.rehint()
114         self.interface.content.style.layout(
115             self.interface.content,
116             WinFormsViewport(native=None, frame=None),
117         )
118         self.native.MinimumSize = Size(
119             int(self.interface.content.layout.width),
120             int(self.interface.content.layout.height) + TITLEBAR_HEIGHT
121         )
122         self.interface.content.refresh()
123 
124         self.native.Show()
125 
126     def winforms_FormClosing(self, event, handler):
127         if self.interface.app.on_exit:
128             self.interface.app.on_exit(self.interface.app)
129 
130     def set_full_screen(self, is_full_screen):
131         self.interface.factory.not_implemented('Window.set_full_screen()')
132 
133     def on_close(self):
134         pass
135 
136     def close(self):
137         self.native.Close()
138 
139     def winforms_resize(self, sender, args):
140         if self.interface.content:
141             # Re-layout the content
142             self.interface.content.refresh()
143 
144     def info_dialog(self, title, message):
145         return WinForms.MessageBox.Show(message, title, WinForms.MessageBoxButtons.OK)
146 
147     def question_dialog(self, title, message):
148         result = WinForms.MessageBox.Show(message, title, WinForms.MessageBoxButtons.YesNo)
149         return result
150 
151     def confirm_dialog(self, title, message):
152         result = WinForms.MessageBox.Show(message, title, WinForms.MessageBoxButtons.OKCancel)
153         # this returns 1 (DialogResult.OK enum) for OK and 2 for Cancel
154         return True if result == WinForms.DialogResult.OK else False
155 
156     def error_dialog(self, title, message):
157         return WinForms.MessageBox.Show(message, title, WinForms.MessageBoxButtons.OK,
158                                         WinForms.MessageBoxIcon.Error)
159 
160     def stack_trace_dialog(self, title, message, content, retry=False):
161         pass
162 
163     def save_file_dialog(self, title, suggested_filename, file_types):
164         dialog = WinForms.SaveFileDialog()
165         dialog.Title = title
166         if suggested_filename is not None:
167             dialog.FileName = suggested_filename
168         if dialog.ShowDialog() == WinForms.DialogResult.OK:
169             return dialog.FileName
170         else:
171             raise ValueError("No filename provided in the save file dialog")
172 
173     def open_file_dialog(self, title, initial_directory, file_types, multiselect):
174         dialog = WinForms.OpenFileDialog()
175         dialog.Title = title
176         if initial_directory is not None:
177             dialog.InitialDirectory = initial_directory
178         if file_types is not None:
179             # FIXME This is the example of Filter string: Text files (*.txt)|*.txt|All files (*.*)|*.*
180 
181             dialog.Filter = ';'.join(["*." + ext for ext in file_types]) + \
182                             "|All files (*.*)|*.*"
183         if multiselect:
184             dialog.Multiselect = True
185         if dialog.ShowDialog() == WinForms.DialogResult.OK:
186             return dialog.FileName
187         else:
188             raise ValueError("No filename provided in the open file dialog")
189 
190     def select_folder_dialog(self, title, initial_directory, multiselect):
191         dialog = WinForms.FolderBrowserDialog()
192         dialog.Title = title
193         if initial_directory is not None:
194             dialog.InitialDirectory = initial_directory
195 
196         if dialog.ShowDialog() == WinForms.DialogResult.OK:
197             return [dialog.SelectedPath]
198         else:
199             raise ValueError("No folder provided in the select folder dialog")
200
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/winforms/toga_winforms/window.py b/src/winforms/toga_winforms/window.py
--- a/src/winforms/toga_winforms/window.py
+++ b/src/winforms/toga_winforms/window.py
@@ -176,10 +176,7 @@
         if initial_directory is not None:
             dialog.InitialDirectory = initial_directory
         if file_types is not None:
-            # FIXME This is the example of Filter string: Text files (*.txt)|*.txt|All files (*.*)|*.*
-
-            dialog.Filter = ';'.join(["*." + ext for ext in file_types]) + \
-                            "|All files (*.*)|*.*"
+            dialog.Filter = self.build_filter(file_types)
         if multiselect:
             dialog.Multiselect = True
         if dialog.ShowDialog() == WinForms.DialogResult.OK:
@@ -197,3 +194,8 @@
             return [dialog.SelectedPath]
         else:
             raise ValueError("No folder provided in the select folder dialog")
+
+    def build_filter(self, file_types):
+        file_string = "{0} files (*.{0})|*.{0}"
+        return '|'.join([file_string.format(ext) for ext in file_types]) + \
+            "|All files (*.*)|*.*"

{"golden_diff": "diff --git a/src/winforms/toga_winforms/window.py b/src/winforms/toga_winforms/window.py\n--- a/src/winforms/toga_winforms/window.py\n+++ b/src/winforms/toga_winforms/window.py\n@@ -176,10 +176,7 @@\n         if initial_directory is not None:\n             dialog.InitialDirectory = initial_directory\n         if file_types is not None:\n-            # FIXME This is the example of Filter string: Text files (*.txt)|*.txt|All files (*.*)|*.*\n-\n-            dialog.Filter = ';'.join([\"*.\" + ext for ext in file_types]) + \\\n-                            \"|All files (*.*)|*.*\"\n+            dialog.Filter = self.build_filter(file_types)\n         if multiselect:\n             dialog.Multiselect = True\n         if dialog.ShowDialog() == WinForms.DialogResult.OK:\n@@ -197,3 +194,8 @@\n             return [dialog.SelectedPath]\n         else:\n             raise ValueError(\"No folder provided in the select folder dialog\")\n+\n+    def build_filter(self, file_types):\n+        file_string = \"{0} files (*.{0})|*.{0}\"\n+        return '|'.join([file_string.format(ext) for ext in file_types]) + \\\n+            \"|All files (*.*)|*.*\"\n", "issue": "Open_File_Dialog crashes on W10 with custom file_type\nfollowing code:\r\n```\r\nfname = self.main_window.open_file_dialog(\r\n  title=\"Open RTF file\",\r\n  multiselect=False,\r\n  file_types=['rtf']\r\n)\r\n```\r\n\r\n## Expected Behavior\r\nshould work fine ond every platform\r\n\r\n## Current Behavior\r\nworks fine on linux, crashes on Windows 10:\r\n```\r\nTraceback (most recent call last):\r\n  File \"C:\\Users\\user\\AppData\\Local\\Programs\\NewGAN Manager\\\\app\\newganmanager\\app.py\", line 301, in action_open_file_dialog\r\n    file_types=['rtf']\r\n  File \"C:\\Users\\user\\AppData\\Local\\Programs\\NewGAN Manager\\\\app_packages\\toga\\window.py\", line 282, in open_file_dialog\r\n    return self._impl.open_file_dialog(title, initial_directory, file_types, multiselect)\r\n  File \"C:\\Users\\user\\AppData\\Local\\Programs\\NewGAN Manager\\\\app_packages\\toga_winforms\\window.py\", line 182, in open_file_dialog\r\n    \"|All files (*.*)|*.*\"\r\nSystem.ArgumentException: Die angegebene Filterzeichenfolge ist ung\u00fcltig. Sie muss eine Beschreibung des Filters gefolgt von einem vertikalen Strich (|) und dem Filtermuster enthalten. Die Zeichenfolgen f\u00fcr andere Filteroptionen m\u00fcssen ebenfalls durch einen vertikalen Strich getrennt werden. Beispiel: \"Textdateien (*.txt)|*.txt|Alle Dateien (*.*)|*.*\".\r\n   bei System.Windows.Forms.FileDialog.set_Filter(String value)\r\n```\r\nTranslated: The provided filter-string is invalid. It must consist of a description of the filter a vertical bar (|) and the filter-pattern. Following the example of the FIXME\r\n\r\n## Steps to reproduce\r\nsee snippet.\r\n\r\n* Python Version (list the specific version number)\r\npython 3.7\r\n\r\n* Operating System and Version (select from the following and list the specific version number; if your OS is not listed, list that as well)\r\n\r\n  - [x] Windows - version: 10\r\n\r\n\r\n* Toga Version (list the specific version number or git hash)\r\n\r\n* Toga Target (the type of app you are trying to generate)\r\n\r\n  - [ ] android\r\n  - [ ] cocoa\r\n  - [ ] django\r\n  - [x] gtk\r\n  - [ ] iOS\r\n  - [ ] tvOS\r\n  - [ ] watchOS\r\n  - [x] winforms\r\n  - [ ] win32\r\n  - [ ] Other (please specify)\r\n\r\n## Proposed Solution\r\nchange https://github.com/beeware/toga/blob/master/src/winforms/toga_winforms/window.py#L181\r\nto\r\n```\r\nfile_string = \"{0} files (*.{0})|*.{0}\"\r\nfil = '|'.join([file_string.format(ext) for ext in file_types]) + \\\r\n                            \"|All files (*.*)|*.*\"\r\n\r\n```\r\nThis is ofc not an ideal solution, because we just add a generic description, but since there is no wrapper for an appropriate datatype I feel this would be a reasonable bridging solution.\r\n\r\nsrc: https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.filedialog.filter?view=netcore-3.1\r\n\r\nP.S: I can't contribute to windows myself, because I barely get my hands on a W10 machine and I just had a few minutes to test it out. Cheers\n", "before_files": [{"content": "from toga import GROUP_BREAK, SECTION_BREAK\n\nfrom .libs import WinForms, Size\n\n\nclass WinFormsViewport:\n    def __init__(self, native, frame):\n        self.native = native\n        self.frame = frame\n        self.baseline_dpi = 96\n\n    @property\n    def width(self):\n        # Treat `native=None` as a 0x0 viewport\n        if self.native is None:\n            return 0\n        return self.native.ClientSize.Width\n\n    @property\n    def height(self):\n        if self.native is None:\n            return 0\n        # Subtract any vertical shift of the frame. This is to allow\n        # for toolbars, or any other viewport-level decoration.\n        return self.native.ClientSize.Height - self.frame.vertical_shift\n\n    @property\n    def dpi(self):\n        if self.native is None:\n            return self.baseline_dpi\n        return self.native.CreateGraphics().DpiX\n\n\nclass Window:\n    def __init__(self, interface):\n        self.interface = interface\n        self.interface._impl = self\n        self.create()\n\n    def create(self):\n        self.native = WinForms.Form(self)\n        self.native.ClientSize = Size(*self.interface._size)\n        self.native.interface = self.interface\n        self.native.Resize += self.winforms_resize\n        self.toolbar_native = None\n        self.toolbar_items = None\n\n    def create_toolbar(self):\n        self.toolbar_native = WinForms.ToolStrip()\n        for cmd in self.interface.toolbar:\n            if cmd == GROUP_BREAK:\n                item = WinForms.ToolStripSeparator()\n            elif cmd == SECTION_BREAK:\n                item = WinForms.ToolStripSeparator()\n            else:\n                if cmd.icon is not None:\n                    native_icon = cmd.icon._impl.native\n                    item = WinForms.ToolStripMenuItem(cmd.label, native_icon.ToBitmap())\n                else:\n                    item = WinForms.ToolStripMenuItem(cmd.label)\n                item.Click += cmd._impl.as_handler()\n                cmd._impl.native.append(item)\n            self.toolbar_native.Items.Add(item)\n\n    def set_position(self, position):\n        pass\n\n    def set_size(self, size):\n        self.native.ClientSize = Size(*self.interface._size)\n\n    def set_app(self, app):\n        pass\n\n    @property\n    def vertical_shift(self):\n        # vertical shift is the toolbar height or 0\n        result = 0\n        try:\n            result += self.native.interface._impl.toolbar_native.Height\n        except AttributeError:\n            pass\n        try:\n            result += self.native.interface._impl.native.MainMenuStrip.Height\n        except AttributeError:\n            pass\n        return result\n\n    def set_content(self, widget):\n        if self.toolbar_native:\n            self.native.Controls.Add(self.toolbar_native)\n            # Create the lookup table of menu items,\n            # then force the creation of the menus.\n        self.native.Controls.Add(widget.native)\n\n        # Set the widget's viewport to be based on the window's content.\n        widget.viewport = WinFormsViewport(native=self.native, frame=self)\n        widget.frame = self\n\n        # Add all children to the content widget.\n        for child in widget.interface.children:\n            child._impl.container = widget\n\n    def set_title(self, title):\n        self.native.Text = title\n\n    def show(self):\n        # The first render of the content will establish the\n        # minimum possible content size; use that to enforce\n        # a minimum window size.\n        TITLEBAR_HEIGHT = WinForms.SystemInformation.CaptionHeight\n        # Now that the content is visible, we can do our initial hinting,\n        # and use that as the basis for setting the minimum window size.\n        self.interface.content._impl.rehint()\n        self.interface.content.style.layout(\n            self.interface.content,\n            WinFormsViewport(native=None, frame=None),\n        )\n        self.native.MinimumSize = Size(\n            int(self.interface.content.layout.width),\n            int(self.interface.content.layout.height) + TITLEBAR_HEIGHT\n        )\n        self.interface.content.refresh()\n\n        self.native.Show()\n\n    def winforms_FormClosing(self, event, handler):\n        if self.interface.app.on_exit:\n            self.interface.app.on_exit(self.interface.app)\n\n    def set_full_screen(self, is_full_screen):\n        self.interface.factory.not_implemented('Window.set_full_screen()')\n\n    def on_close(self):\n        pass\n\n    def close(self):\n        self.native.Close()\n\n    def winforms_resize(self, sender, args):\n        if self.interface.content:\n            # Re-layout the content\n            self.interface.content.refresh()\n\n    def info_dialog(self, title, message):\n        return WinForms.MessageBox.Show(message, title, WinForms.MessageBoxButtons.OK)\n\n    def question_dialog(self, title, message):\n        result = WinForms.MessageBox.Show(message, title, WinForms.MessageBoxButtons.YesNo)\n        return result\n\n    def confirm_dialog(self, title, message):\n        result = WinForms.MessageBox.Show(message, title, WinForms.MessageBoxButtons.OKCancel)\n        # this returns 1 (DialogResult.OK enum) for OK and 2 for Cancel\n        return True if result == WinForms.DialogResult.OK else False\n\n    def error_dialog(self, title, message):\n        return WinForms.MessageBox.Show(message, title, WinForms.MessageBoxButtons.OK,\n                                        WinForms.MessageBoxIcon.Error)\n\n    def stack_trace_dialog(self, title, message, content, retry=False):\n        pass\n\n    def save_file_dialog(self, title, suggested_filename, file_types):\n        dialog = WinForms.SaveFileDialog()\n        dialog.Title = title\n        if suggested_filename is not None:\n            dialog.FileName = suggested_filename\n        if dialog.ShowDialog() == WinForms.DialogResult.OK:\n            return dialog.FileName\n        else:\n            raise ValueError(\"No filename provided in the save file dialog\")\n\n    def open_file_dialog(self, title, initial_directory, file_types, multiselect):\n        dialog = WinForms.OpenFileDialog()\n        dialog.Title = title\n        if initial_directory is not None:\n            dialog.InitialDirectory = initial_directory\n        if file_types is not None:\n            # FIXME This is the example of Filter string: Text files (*.txt)|*.txt|All files (*.*)|*.*\n\n            dialog.Filter = ';'.join([\"*.\" + ext for ext in file_types]) + \\\n                            \"|All files (*.*)|*.*\"\n        if multiselect:\n            dialog.Multiselect = True\n        if dialog.ShowDialog() == WinForms.DialogResult.OK:\n            return dialog.FileName\n        else:\n            raise ValueError(\"No filename provided in the open file dialog\")\n\n    def select_folder_dialog(self, title, initial_directory, multiselect):\n        dialog = WinForms.FolderBrowserDialog()\n        dialog.Title = title\n        if initial_directory is not None:\n            dialog.InitialDirectory = initial_directory\n\n        if dialog.ShowDialog() == WinForms.DialogResult.OK:\n            return [dialog.SelectedPath]\n        else:\n            raise ValueError(\"No folder provided in the select folder dialog\")\n", "path": "src/winforms/toga_winforms/window.py"}], "after_files": [{"content": "from toga import GROUP_BREAK, SECTION_BREAK\n\nfrom .libs import WinForms, Size\n\n\nclass WinFormsViewport:\n    def __init__(self, native, frame):\n        self.native = native\n        self.frame = frame\n        self.baseline_dpi = 96\n\n    @property\n    def width(self):\n        # Treat `native=None` as a 0x0 viewport\n        if self.native is None:\n            return 0\n        return self.native.ClientSize.Width\n\n    @property\n    def height(self):\n        if self.native is None:\n            return 0\n        # Subtract any vertical shift of the frame. This is to allow\n        # for toolbars, or any other viewport-level decoration.\n        return self.native.ClientSize.Height - self.frame.vertical_shift\n\n    @property\n    def dpi(self):\n        if self.native is None:\n            return self.baseline_dpi\n        return self.native.CreateGraphics().DpiX\n\n\nclass Window:\n    def __init__(self, interface):\n        self.interface = interface\n        self.interface._impl = self\n        self.create()\n\n    def create(self):\n        self.native = WinForms.Form(self)\n        self.native.ClientSize = Size(*self.interface._size)\n        self.native.interface = self.interface\n        self.native.Resize += self.winforms_resize\n        self.toolbar_native = None\n        self.toolbar_items = None\n\n    def create_toolbar(self):\n        self.toolbar_native = WinForms.ToolStrip()\n        for cmd in self.interface.toolbar:\n            if cmd == GROUP_BREAK:\n                item = WinForms.ToolStripSeparator()\n            elif cmd == SECTION_BREAK:\n                item = WinForms.ToolStripSeparator()\n            else:\n                if cmd.icon is not None:\n                    native_icon = cmd.icon._impl.native\n                    item = WinForms.ToolStripMenuItem(cmd.label, native_icon.ToBitmap())\n                else:\n                    item = WinForms.ToolStripMenuItem(cmd.label)\n                item.Click += cmd._impl.as_handler()\n                cmd._impl.native.append(item)\n            self.toolbar_native.Items.Add(item)\n\n    def set_position(self, position):\n        pass\n\n    def set_size(self, size):\n        self.native.ClientSize = Size(*self.interface._size)\n\n    def set_app(self, app):\n        pass\n\n    @property\n    def vertical_shift(self):\n        # vertical shift is the toolbar height or 0\n        result = 0\n        try:\n            result += self.native.interface._impl.toolbar_native.Height\n        except AttributeError:\n            pass\n        try:\n            result += self.native.interface._impl.native.MainMenuStrip.Height\n        except AttributeError:\n            pass\n        return result\n\n    def set_content(self, widget):\n        if self.toolbar_native:\n            self.native.Controls.Add(self.toolbar_native)\n            # Create the lookup table of menu items,\n            # then force the creation of the menus.\n        self.native.Controls.Add(widget.native)\n\n        # Set the widget's viewport to be based on the window's content.\n        widget.viewport = WinFormsViewport(native=self.native, frame=self)\n        widget.frame = self\n\n        # Add all children to the content widget.\n        for child in widget.interface.children:\n            child._impl.container = widget\n\n    def set_title(self, title):\n        self.native.Text = title\n\n    def show(self):\n        # The first render of the content will establish the\n        # minimum possible content size; use that to enforce\n        # a minimum window size.\n        TITLEBAR_HEIGHT = WinForms.SystemInformation.CaptionHeight\n        # Now that the content is visible, we can do our initial hinting,\n        # and use that as the basis for setting the minimum window size.\n        self.interface.content._impl.rehint()\n        self.interface.content.style.layout(\n            self.interface.content,\n            WinFormsViewport(native=None, frame=None),\n        )\n        self.native.MinimumSize = Size(\n            int(self.interface.content.layout.width),\n            int(self.interface.content.layout.height) + TITLEBAR_HEIGHT\n        )\n        self.interface.content.refresh()\n\n        self.native.Show()\n\n    def winforms_FormClosing(self, event, handler):\n        if self.interface.app.on_exit:\n            self.interface.app.on_exit(self.interface.app)\n\n    def set_full_screen(self, is_full_screen):\n        self.interface.factory.not_implemented('Window.set_full_screen()')\n\n    def on_close(self):\n        pass\n\n    def close(self):\n        self.native.Close()\n\n    def winforms_resize(self, sender, args):\n        if self.interface.content:\n            # Re-layout the content\n            self.interface.content.refresh()\n\n    def info_dialog(self, title, message):\n        return WinForms.MessageBox.Show(message, title, WinForms.MessageBoxButtons.OK)\n\n    def question_dialog(self, title, message):\n        result = WinForms.MessageBox.Show(message, title, WinForms.MessageBoxButtons.YesNo)\n        return result\n\n    def confirm_dialog(self, title, message):\n        result = WinForms.MessageBox.Show(message, title, WinForms.MessageBoxButtons.OKCancel)\n        # this returns 1 (DialogResult.OK enum) for OK and 2 for Cancel\n        return True if result == WinForms.DialogResult.OK else False\n\n    def error_dialog(self, title, message):\n        return WinForms.MessageBox.Show(message, title, WinForms.MessageBoxButtons.OK,\n                                        WinForms.MessageBoxIcon.Error)\n\n    def stack_trace_dialog(self, title, message, content, retry=False):\n        pass\n\n    def save_file_dialog(self, title, suggested_filename, file_types):\n        dialog = WinForms.SaveFileDialog()\n        dialog.Title = title\n        if suggested_filename is not None:\n            dialog.FileName = suggested_filename\n        if dialog.ShowDialog() == WinForms.DialogResult.OK:\n            return dialog.FileName\n        else:\n            raise ValueError(\"No filename provided in the save file dialog\")\n\n    def open_file_dialog(self, title, initial_directory, file_types, multiselect):\n        dialog = WinForms.OpenFileDialog()\n        dialog.Title = title\n        if initial_directory is not None:\n            dialog.InitialDirectory = initial_directory\n        if file_types is not None:\n            dialog.Filter = self.build_filter(file_types)\n        if multiselect:\n            dialog.Multiselect = True\n        if dialog.ShowDialog() == WinForms.DialogResult.OK:\n            return dialog.FileName\n        else:\n            raise ValueError(\"No filename provided in the open file dialog\")\n\n    def select_folder_dialog(self, title, initial_directory, multiselect):\n        dialog = WinForms.FolderBrowserDialog()\n        dialog.Title = title\n        if initial_directory is not None:\n            dialog.InitialDirectory = initial_directory\n\n        if dialog.ShowDialog() == WinForms.DialogResult.OK:\n            return [dialog.SelectedPath]\n        else:\n            raise ValueError(\"No folder provided in the select folder dialog\")\n\n    def build_filter(self, file_types):\n        file_string = \"{0} files (*.{0})|*.{0}\"\n        return '|'.join([file_string.format(ext) for ext in file_types]) + \\\n            \"|All files (*.*)|*.*\"\n", "path": "src/winforms/toga_winforms/window.py"}]}