0

Ok, I have a very simple project to learn about WPF following this video tutorial: https://www.youtube.com/watch?v=Vjldip84CXQ

Everything is OK (and by OK I mean the project can be built AND run)... until I try to change a little part in the XAML from:

  <ComboBox SelectedIndex="0">
    <ComboBoxItem>Painted</ComboBoxItem>
    <ComboBoxItem>Not Painted</ComboBoxItem>
  </ComboBox>

to:

  <ComboBox x:Name="FinishComboBox" SelectedIndex="0" SelectionChanged="FinishComboBox_SelectionChanged">
    <ComboBoxItem>Painted</ComboBoxItem>
    <ComboBoxItem>Not Painted</ComboBoxItem>
  </ComboBox>

Then it gives me this error, "PresentationFramework.pdb not loaded". And, strangely - at least to me, the solution can be built but CANNOT be run. The error is generated when I try to run (such as by pressing F5 in VS) the solution.

enter image description here

And yes, it is really caused by the XAML change, because if I change the XAML back to:

  <!--<ComboBox x:Name="FinishComboBox" SelectedIndex="0" SelectionChanged="FinishComboBox_SelectionChanged">-->
  <ComboBox SelectedIndex="0">
    <ComboBoxItem>Painted</ComboBoxItem>
    <ComboBoxItem>Not Painted</ComboBoxItem>
  </ComboBox>

It is working, clean and fine. So my question is obviously why is this so?

I tried some solutions like suggested in:

That includes:

  1. deleted bin and obj folder from the startup project folder and rebuild the solution
  2. delete reference to the PresentationFramework then retarget your application framwork and then add PresentationFramework reference again or modified some debug options, clean and rebuild the project.
  3. Change settings in Debug -> Options -> Debugging -> General, uncheck "Require source files to exactly match the original version"
  4. Do "Load all symbols" and "Empty Symbol Cache" in Debug -> Options -> Debugging -> Symbols for "All modules, unless excluded"
  5. some other little things...

But nothing works. Any other solution?

Here is my complete code:

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfBasics {
  /// <summary>
  /// Interaction logic for MainWindow.xaml
  /// </summary>
  public partial class MainWindow : Window {
    public MainWindow() {
      InitializeComponent();
    }

    private void ApplyButton_Click(object sender, RoutedEventArgs e) {
      MessageBox.Show($"The description is: {DescriptionText.Text}"); //See how crazy C# is when making things easy for string printing AND it can handle null!!
    }

    private void ResetButton_Click(object sender, RoutedEventArgs e) {
      WeldCheckBox.IsChecked = AssemblyCheckBox.IsChecked = PlasmaCheckBox.IsChecked = LaserCheckBox.IsChecked = PurchaseCheckBox.IsChecked = 
      LatheCheckBox.IsChecked = DrillCheckBox.IsChecked = FoldCheckBox.IsChecked = RollCheckBox.IsChecked = SawCheckBox.IsChecked = false;
    }

    private void CheckBox_Checked(object sender, RoutedEventArgs e) {
      int length = string.IsNullOrWhiteSpace(LengthText.Text) ? 0 : int.Parse(LengthText.Text);
      length += ((CheckBox)sender).Content.ToString().Length;
      LengthText.Text = length.ToString();
    }

    private void CheckBox_Unchecked(object sender, RoutedEventArgs e) {
      int length = string.IsNullOrWhiteSpace(LengthText.Text) ? 0 : int.Parse(LengthText.Text);
      length -= ((CheckBox)sender).Content.ToString().Length;
      LengthText.Text = length.ToString();
    }

    private void FinishComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
      var comboBox = (ComboBox)sender;
      var value = (ComboBoxItem)comboBox.SelectedValue;
      NoteText.Text = (string)value.Content;
    }
  }
}

XAML

<Window x:Class="WpfBasics.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfBasics"
        mc:Ignorable="d"
        Title="WPF Basics v1.0" Height="800" Width="400">

  <Border Padding="10">
    <StackPanel>
      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="*"/>
          <ColumnDefinition Width="*"/>
          <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Button x:Name="ApplyButton" Click="ApplyButton_Click" Margin="0 0 10 0" Grid.Column="0" Content="Apply"/>
        <Button x:Name="ResetButton" Click="ResetButton_Click" Margin="0 0 0 0" Grid.Column="1" Content="Reset"/>
        <Button Margin="10 0 0 0" Grid.Column="2" Content="Refresh"/>
      </Grid>

      <!--Margin shorthand 0 10 means left-right = 0, top bottom = 10-->
      <!--Pulse Properties-->
      <TextBlock Text="Pulse Properties" FontWeight="Bold" Margin="0 10"/>

      <!--Description-->
      <TextBlock Text="Description"/>
      <TextBox x:Name="DescriptionText" Padding="2" />

      <!--Status and Revision-->
      <Grid Margin="0 5 0 0">
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="2*"/>
          <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <StackPanel Grid.Column="0" Margin="0 0 10 0">
          <TextBlock Text="Status"/>
          <TextBox Padding="2" IsReadOnly="True" Background="#eeeeee"/>
        </StackPanel>

        <StackPanel Grid.Column="1">
          <TextBlock Text="Revision"/>
          <TextBox Padding="2" IsReadOnly="True" Background="#eeeeee"/>
        </StackPanel>

      </Grid>

      <!--Part Number-->
      <TextBlock Text="Part Number" Margin="0 5 0 0"/>
      <TextBox Padding="2" IsReadOnly="True" Background="#eeeeee"/>

      <!--Raw Material-->
      <TextBlock Text="Raw Material" FontWeight="Bold" Margin="0 10"/>

      <!--Material-->
      <TextBlock Text="Material"/>
      <ComboBox />

      <!--Manufacturing Info-->
      <TextBlock Text="Manufacturing Info" FontWeight="Bold" Margin="0 10"/>

      <!--Work Centres-->
      <TextBlock Text="Work Centres"/>

      <!--Checkboxes-->
      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="*"/>
          <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <StackPanel Grid.Column="0" Margin="0 0 10 0">
          <CheckBox Unchecked="CheckBox_Unchecked" Checked="CheckBox_Checked" x:Name="WeldCheckBox" Content="Weld"/>
          <CheckBox Unchecked="CheckBox_Unchecked" Checked="CheckBox_Checked" x:Name="AssemblyCheckBox" Content="Assembly"/>
          <CheckBox Unchecked="CheckBox_Unchecked" Checked="CheckBox_Checked" x:Name="PlasmaCheckBox" Content="Plasma"/>
          <CheckBox Unchecked="CheckBox_Unchecked" Checked="CheckBox_Checked" x:Name="LaserCheckBox" Content="Laser"/>
          <CheckBox Unchecked="CheckBox_Unchecked" Checked="CheckBox_Checked" x:Name="PurchaseCheckBox" Content="Purchase"/>
        </StackPanel>

        <StackPanel Grid.Column="1">
          <CheckBox Unchecked="CheckBox_Unchecked" Checked="CheckBox_Checked" x:Name="LatheCheckBox" Content="Lathe"/>
          <CheckBox Unchecked="CheckBox_Unchecked" Checked="CheckBox_Checked" x:Name="DrillCheckBox" Content="Drill"/>
          <CheckBox Unchecked="CheckBox_Unchecked" Checked="CheckBox_Checked" x:Name="FoldCheckBox" Content="Fold"/>
          <CheckBox Unchecked="CheckBox_Unchecked" Checked="CheckBox_Checked" x:Name="RollCheckBox" Content="Roll"/>
          <CheckBox Unchecked="CheckBox_Unchecked" Checked="CheckBox_Checked" x:Name="SawCheckBox" Content="Saw"/>
        </StackPanel>
      </Grid>

      <!--Length-->
      <TextBlock Text="Length" Margin="0 5 0 0"/>
      <TextBox x:Name="LengthText" Padding="2"/>

      <!--Mass-->
      <TextBlock Text="Mass" Margin="0 5 0 0"/>
      <TextBox x:Name="MassText" Padding="2" IsReadOnly="True" Background="#eeeeee"/>

      <!--Finish-->
      <TextBlock Text="Finish" Margin="0 5 0 0"/>
      <ComboBox x:Name="FinishComboBox" SelectedIndex="0" SelectionChanged="FinishComboBox_SelectionChanged">
      <!--ok if I use the code below-->
      <!--<ComboBox SelectedIndex="0">-->
        <ComboBoxItem>Painted</ComboBoxItem>
        <ComboBoxItem>Not Painted</ComboBoxItem>
      </ComboBox>

      <!--Purchase Information-->
      <TextBlock Text="Purchase Information" Margin="0 5 0 0"/>
      <ComboBox SelectedIndex="0">
        <ComboBoxItem>Rubber</ComboBoxItem>
        <ComboBoxItem>Not Rubber</ComboBoxItem>
      </ComboBox>

      <!--Supplier Name-->
      <TextBlock Text="Supplier Name" Margin="0 5 0 0"/>
      <TextBox Padding="2"/>

      <!--Supplier Code-->
      <TextBlock Text="Supplier Code" Margin="0 5 0 0"/>
      <TextBox Padding="2"/>

      <!--Additional Information-->
      <TextBlock Text="Additional Information" FontWeight="Bold" Margin="0 10"/>

      <!--Note-->
      <TextBlock Text="Note"/>
      <TextBox x:Name="NoteText" Padding="2"/>

    </StackPanel>
  </Border>
</Window>
Ian
  • 30,182
  • 19
  • 69
  • 107
  • 1
    Just a note (because you want to learn WPF). You don't have to set `x:Name="FinishComboBox"`, since your code isn't using the generated field. – Clemens Jun 30 '17 at 05:36
  • 2
    As another note, you should access the ComboBox's selected item by its `SelectedItem` property instead of `SelectedValue`, which is meant to work in combination with `SelectedValuePath`. – Clemens Jun 30 '17 at 05:53
  • 2
    The next step would be to learn how to get rid of all those event handlers and use MVVM. 1.Create a view model class. 2.Assign an instance of the VM to the DataContext property of the window. 3.Bind the ItemsSource property to a VM property that is a collection of strings. 4.Bind the ComboBox's SelectedItem to a selected item property in the VM. 5.Bind the TextBlock's Text to the same property. – Clemens Jun 30 '17 at 06:11
  • 1
    Thanks, I haven't learned about `MVVM`, `DataContext`, or `Binding` in `WPF` yet... But I should probably do that once I grasp the basic concept of WPF. – Ian Jun 30 '17 at 06:15

1 Answers1

1

The thing is, that you try to set the text of "NoteText" while you initialize the controls. But your "NoteText" isn't really loaded yet. The solution would be to remove the SelectedIndex from the XAML and select index 0 after InitializeComponent.

    public MainWindow()
    {
        InitializeComponent();
        FinishComboBox.SelectedIndex = 0;
    }
  • Probably not the cleanest solution but it should at least work. –  Jun 30 '17 at 05:49
  • You are absolutely right! Oh, how could this generate .pdb not loaded error? Could you explain about this too? Thanks anyway! – Ian Jun 30 '17 at 05:50
  • And yes, I did not do exactly like what you showed. Instead, I have a flag `isLoaded` to indicate that if the `InitializeComponent` is not fully loaded, then the flag will be `false` and as long as it is false the `SelectionChanged` event would immediately `return`. – Ian Jun 30 '17 at 05:51
  • @Ian Instead of that flag you can simply check whether `NoteText` is null or not. Another alternative would be to attach the SelectionChanged handler in code behind after InitializeComponent. – Clemens Jun 30 '17 at 05:55
  • In the exception it said `Object reference not set to an instance of an Object.`. I think this is a pretty good description of the problem. Well... happy that I could help. –  Jun 30 '17 at 05:56
  • @lan isLoaded is probably a much cleaner solution. –  Jun 30 '17 at 05:58
  • @Clemens, Ozeanis those are certainly some other alternatives. I normally use `isLoaded` because you only need to do the same thing for all other event handler, while if you check individual item, you would check *different* item for different handlers which use different items. And as for create the handler *after* the `InitializeComponent`, that alternative I both haven't learned and may require to write more codes. But thanks for the suggestions again... – Ian Jun 30 '17 at 06:00
  • @Ozeanis null reference, I should have put more attention to that *small* box rather than focusing on the *big* error box... lol – Ian Jun 30 '17 at 06:01
  • @Ozeanis nope, unlike in previous VS, I suppose, in VS2017, I was directed to that large "no symbol loaded" window rather than to the .cs code which generates the null exception. That's why I got tricked... And yes, when I used WinForm in the past, I would immediately notice the error caused by using of an item before it is fully initialized... But since I am new to both WPF *and* VS2017, I thought I made *bigger* mistake... something along that line and I got tricked... Thanks anyway for your help. I appreciate it! – Ian Jun 30 '17 at 06:06