Bind to UIElement in code-behind crashing

2019-09-10 03:40发布

问题:

In my code, I have an UIElement variable I set with certain button presses. Now, I have this variable:

public UIElement currentMenu;

Set to this value:

currentMenu = (UIElement)Resources["Home"];

I get it from the Resources so I don't have to manage it messily in the code-behind, I will export the Resources to a seperate ResourceDictionary once I get this problem solved.

My SplitView looks like this:

<SplitView x:Name="NavPane" OpenPaneLength="250" CompactPaneLength="50" Content="{x:Bind currentMenu}" DisplayMode="CompactOverlay" IsPaneOpen="False" PaneClosing="NavPane_PaneClosing">

The prblem comes in at this point, the Binding crashes the entire application with an unhndled win32 exception. I get no description and the error code changes every time. I have checked with break points whether this behaviour is actually caused by the binding, and it is.

If you have any suggestions on what might be going wrong here, please post an answer. I will supply any additional information needed (if reasonable, I'm not going to send you my entire project files)

Any help is appreciated!

回答1:

Your problem that you are using a variable, not a property.

private UIElement currentMenu;
public string CurrentMenu
{
   get { return currentMenu; }
   set { 
         currentMenu=value);
         OnPropertyChanged("CurrentMenu");
       }
} 

So the basic rules to bind Control to a "varaible":

  • Variable should be a property, not a field.
  • it should be public.
  • Either a notifying property (suitable for model classes) or a dependency property (suitable for view classes)

To notify UI you should implement INotifyPropertyChanged:

public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

Update:

Your Bidning should looks like:

<SplitView x:Name="NavPane" OpenPaneLength="250" CompactPaneLength="50" 
       Content="{Binding CurrentMenu}" DisplayMode="CompactOverlay" IsPaneOpen="False"
       PaneClosing="NavPane_PaneClosing">


回答2:

I have found the answer to my question!

Namely, this was not the way to do it. Instead, I declared a Frame inside the Content of the SplitView:

<SplitView.Content>
    <Frame x:Name="activeMenu"/>
</SplitView.Content>

Then, I use the Frame.Navigate() function to load my menus into the Frame:

    public MainPage()
    {
        DataContext = this;
        this.InitializeComponent();
        SetMenu(0);
    }

    private void SetMenu(int key)
    {
        switch (key)
        {
            case 0:
                activeMenu.Navigate(typeof(HomeMenu));
                break;
            //You can add in as many cases as you need
        }
    }

What you then need is to set all the menus you want as separate Pages within your project files. in this example, HomeMenu.xaml contains the grid for the menu people see upon starting up the app.

This solved the problem, but thank you to everyone (StepUp) who contributed to the original (unfortunately unsuccessful) solution!