0

I have a RibbonComboBox and would like to set the combobox selection based on my application settings, as well as store any changes to the application setting when the combobox selection changes. I tried to make this work, but the initial selection does not work, and changing the selection does not seem to update the setting value (I do a Properties.Settings.Default.Save() when the application exits).

Settings.settings

In my xaml I have:

 xmlns:p="clr-namespace:Scanning.Properties"

 <RibbonComboBox IsEditable="False">
     <RibbonGallery SelectedItem="{Binding Source={x:Static p:Settings.Default}, Path=profile1_papersize, Mode=TwoWay}">
         <RibbonGalleryCategory>
             <RibbonGalleryItem Content="A4" />
             <RibbonGalleryItem Content="B5" />
             <RibbonGalleryItem Content="Letter" />
             <RibbonGalleryItem Content="Legal" />
         </RibbonGalleryCategory>
     </RibbonGallery>
 </RibbonComboBox>

Any idea what I need to change to make it set the value based on the settings, and update the application settings when the selection changes? I'm very new to C# and WPF. Thanks!

Sean N.
  • 963
  • 2
  • 10
  • 23

1 Answers1

1

First see this answer.

You likely don't want a Static binding, which needs a static instance of the specified object in the Resources somewhere (such as <Window.Resources>. Since you're potentially changing the value, I would instead set the DataContext of the RibbonComboBox.

<RibbonComboBox IsEditable="False" DataContext="{Binding Path=DefaultSettings}">
    <RibbonGallery SelectedItem="{Binding Path=profile1_papersize, Mode=TwoWay}">
        <RibbonGalleryCategory ItemsSource="{Binding Path=PaperSizes}">
        </RibbonGalleryCategory>
    </RibbonGallery>
</RibbonComboBox>

In your codebehind (Edit: sorry, this should be in your Model, with the necessary interface changes to expose the property, if applicable):

public YourModel : INotifyPropertyChanged
{
    public YourModel()
    {
        // Contructor code...
    }

    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;
    #endregion INotifyPropertyChanged Members

    public void SaveSettings()
    {
        // code to copy this._defaultSettings to Scanning.Properties.Settings.Default
        Scanning.Properties.Settings.Default.profile1_papersize = this._defaultSettings.profile1_papersize;
        Scanning.Properties.Settings.Default.OtherProperty1 = this._defaultSettings.Property1;
        Scanning.Properties.Settings.Default.OtherProperty2 = this._defaultSettings.Property2;
        Scanning.Properties.Settings.Default.OtherProperty3 = this._defaultSettings.Property3;
        // code to save Scanning.Properties.Settings.Default
    }

    private static readonly List<string> defaultPaperSizes = new List<string> 
                                                             {
                                                                 "A4",
                                                                 "B5",
                                                                 "Letter",
                                                                 "Legal",
                                                             };
    private List<string> _paperSizes;
    public List<string> PaperSizes
    {
        get
        {
            if (this._paperSizes = null) this.PaperSizes = defaultPaperSizes;
            return this._paperSizes;
        }
        set
        {
            this._paperSizes = value;
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs("PaperSizes"));
        }
    }

    private YourSettingsType _defaultSettings;
    public YourSettingsType DefaultSettings
    { 
        get 
        { 
            if (this._defaultSettings == null) this.DefaultSettings = Scanning.Properties.Settings.Default; 
            return this._defaultSettings;
        }
        set 
        { 
            this._defaultSettings = value;
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs("DefaultSettings"));
        }
    }
}

Edit 2: use the above edited code. You'll need to change SaveSettings to apply the properties of this._defaultSettings and then call it somewhere, such as in the event handler for a "Save" Button.Click event or something.

Edit 3: You'll need to specify a List<string> as the source for the RibbonGalleryCategory bit.

Community
  • 1
  • 1
klugerama
  • 3,312
  • 19
  • 25
  • 1
    This is the right answer - just add an implementation of INotifyPropertyChanged to this, and you can bind TwoWay with notifications. – Troels Larsen Jul 03 '14 at 20:07
  • @TroelsLarsen Oh yeah, forgot about `INotifyPropertyChanged`. I will edit also to show how to use the settings. – klugerama Jul 03 '14 at 20:23
  • @klugerama, this is a great example, I think i'm almost there. I gave you the bounty points. I stumbled a bit because I left out the YourModel() constructor. I think an empty constructor is required. I think the last problem I have, is that the settings values are getting stored as the string "System.Windows.Controls.Ribbon.RibbonGalleryItem: Letter" instead of just "Letter". Is there an easy work-around for this? – Sean N. Jul 07 '14 at 19:04
  • @SeanN. Maybe use `SelectedValue` instead of `SelectedItem` in the XAML. – klugerama Jul 07 '14 at 19:51
  • @klugerama, changed to SelectedValue and it behaves the same. Somehow I need to drop RibbonGalleryItem.Content into _defaultSettings.profile1_papersize instead of a RibbonGalleryItem. I'm not sure how to accomplish this. Thanks. – Sean N. Jul 08 '14 at 20:02
  • @SeanN. You're right, sorry. Edited (even) further. – klugerama Jul 09 '14 at 19:45