public void ProvideSearchSettings(IVsUIDataSource pSearchSettings) { SetIntValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.ControlMaxWidth, 200); SetIntValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.SearchStartType, (int)VSSEARCHSTARTTYPE.SST_DELAYED); SetIntValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.SearchStartDelay, 100); SetBoolValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.SearchUseMRU, true); SetBoolValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.PrefixFilterMRUItems, false); SetIntValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.MaximumMRUItems, 25); SetStringValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.SearchWatermark, ServicesVSResources.Search_Settings); SetBoolValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.SearchPopupAutoDropdown, false); SetStringValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.ControlBorderThickness, "1"); SetIntValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.SearchProgressType, (int)VSSEARCHPROGRESSTYPE.SPT_INDETERMINATE); void SetBoolValue(IVsUIDataSource source, string property, bool value) { var valueProp = BuiltInPropertyValue.FromBool(value); _ = source.SetValue(property, valueProp); } void SetIntValue(IVsUIDataSource source, string property, int value) { var valueProp = BuiltInPropertyValue.Create(value); _ = source.SetValue(property, valueProp); } void SetStringValue(IVsUIDataSource source, string property, string value) { var valueProp = BuiltInPropertyValue.Create(value); _ = source.SetValue(property, valueProp); } }
private static void EnableNewsFeed( ) { // This is where things get UGLY/Fragile try { // In VS2019 the DownloadEnabled property binding for the data source was removed so, // this needs to add enough support back to allow the XAML UI to correctly see // the property from the source to trigger downloading contents of the feed. var feedControl = RestoreIdeUIOptionsPage.FindChildElement(Application.Current.MainWindow, e => e.GetType( ).Name == "RssFeedControl"); // data types, property names etc.. of internal types was determined by attaching the debugger // and the Live XAML viewer to see what the types are. Obviously this is fragile, but we have // little choice when the VS team has gone to great lengths to make it hard to keep perfectly good working UI. // DataContext for the RssFeedControl is an StartPageDataSource wrapped inside of an internal DataSource type var ds = ( DataSource )feedControl.DataContext; // StartPageDataSource has an "Rss" property that contains an instance of the internal RssFeedDataSource type var rss = ( DataSource )ds.GetValue("Rss"); var field = typeof(DataSource).GetField("innerSource", BindingFlags.Instance | BindingFlags.NonPublic); // RssFeedDataSource, while internal, derives from the public UIDataSource type var rssd = ( UIDataSource )field.GetValue(rss); var rssdType = rssd.GetType( ); // RssFeed property resolves to dead link for Community editions, so reset it to // the same link as other SKUs var feedProp = rssdType.GetRuntimeProperty("RssFeed"); string currentFeed = ( string )feedProp.GetValue(rssd); string newFeed = currentFeed.Replace(CommunityLinkId, CorrectedLinkId); feedProp.SetValue(rssd, newFeed); // need to set the _announcementsFeed as it backs the Get only AnnouncementsFeed property var announcmentsFeedField = rssdType.GetField("_announcementsFeed", BindingFlags.NonPublic | BindingFlags.Instance); announcmentsFeedField.SetValue(rssd, newFeed); // RssFeedDataSourceBase declares a virtual "OnPropertyChanged" that updates the rest, // so force a change of the DownloadEnabled property var method = rssdType.GetMethod("OnPropertyChanged", BindingFlags.Instance | BindingFlags.Public); if (method != null) { object[] parameters = { /*IVsUIDataSource ds*/ null, "DownloadEnabled", /*IVsUIObject pVarOld*/ null, BuiltInPropertyValue.FromBool(true) }; /*void*/ _ = method.Invoke(rssd, parameters); } } catch { /* NOP */ } }