Adding custom DialogPreference to xml file - c#

I've implemented this custom DialogPreference in C# with Xamarin however I'm having issues adding it to my xml file.
namespace Client.Android
{
public class TimePreference : DialogPreference
{
private int lastHour = 0;
private int lastMinute = 0;
private TimePicker picker = null;
public static int GetHour(string time)
{
string[] pieces = time.Split (':');
return Convert.ToInt32 (pieces [0]);
}
public static int GetMinute(string time)
{
string[] pieces = time.Split (':');
return Convert.ToInt32 (pieces [1]);
}
public TimePreference(Context context, IAttributeSet attSet) : base(context, attSet)
{
SetPositiveButtonText (Resource.String.time_preference_set);
SetNegativeButtonText (Resource.String.time_preference_cancel);
}
protected override View OnCreateDialogView ()
{
picker = new TimePicker (Context);
return picker;
}
protected override void OnBindDialogView (View view)
{
base.OnBindDialogView (view);
picker.CurrentHour = (Java.Lang.Integer) lastHour;
picker.CurrentMinute = (Java.Lang.Integer) lastMinute;
}
protected override void OnDialogClosed (bool positiveResult)
{
base.OnDialogClosed (positiveResult);
if (positiveResult) {
lastHour = (int) picker.CurrentHour;
lastMinute = (int) picker.CurrentMinute;
string time = lastHour + ":" + lastMinute;
if (CallChangeListener (time)) {
PersistString (time);
}
}
}
protected override Java.Lang.Object OnGetDefaultValue (TypedArray a, int index)
{
return a.GetString (index);
}
protected override void OnSetInitialValue (bool restorePersistedValue, Java.Lang.Object defaultValue)
{
string time = string.Empty;
if (restorePersistedValue) {
if (defaultValue == null) {
time = GetPersistedString ("00:00");
} else {
time = GetPersistedString (defaultValue.ToString ());
}
} else {
time = defaultValue.ToString ();
}
lastHour = GetHour (time);
lastMinute = GetMinute (time);
}
}
}
My projects name/default namespace is "Client.Android" and I've tried adding it to my xml file like so:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="#string/pref_foo" >
...
<Client.Android.TimePreference
android:title="#string/pref_bar"
android:key="#string/prefkey_bar"
android:defaultValue="12:00" />
...
</PreferenceCategory>
</PreferenceScreen>
But I get the following exception on AddPreferencesFromResource(Resource.Xml.settings); of my OnCreate method:
Android.Views.InflateException: Binary XML file line #32: Error inflating class Client.Android.TimePreference
at Android.Runtime.JNIEnv.CallNonvirtualVoidMethod (intptr,intptr,intptr,Android.Runtime.JValue[]) [0x00084] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.12-series/7f0e3d3c/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:895
at Android.Preferences.PreferenceActivity.AddPreferencesFromResource (int) [0x00070] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.12-series/7f0e3d3c/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Android.Preferences.PreferenceActivity.cs:729
at Client.Android.SettingsActivity.OnCreate (Android.OS.Bundle) [0x00015] in c:\pushtotalk\Client.Android\SettingsActivity.cs:45
at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) [0x00011] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.12-series/7f0e3d3c/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Android.App.Activity.cs:2178
at at (wrapper dynamic-method) object.7c9f4d4d-9496-4803-b019-cd453beeee8b (intptr,intptr,intptr) <IL 0x00017, 0x00043>
at --- End of managed exception stack trace ---
at android.view.InflateException: Binary XML file line #32: Error inflating class Client.Android.TimePreference
at at android.preference.GenericInflater.createItemFromTag(GenericInflater.java:441)
at at android.preference.GenericInflater.rInflate(GenericInflater.java:481)
at at android.preference.GenericInflater.rInflate(GenericInflater.java:493)
at at android.preference.GenericInflater.inflate(GenericInflater.java:326)
at at android.preference.GenericInflater.inflate(GenericInflater.java:263)
at at android.preference.PreferenceManager.inflateFromResource(PreferenceManager.java:272)
at at android.preference.PreferenceActivity.addPreferencesFromResource(PreferenceActivity.java:1472)
at at client.android.SettingsActivity.n_onCreate(Native Method)
at at client.android.SettingsActivity.onCreate(SettingsActivity.java:32)
at at android.app.Activity.performCreate(Activity.java:5231)
at at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
at at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at at android.app.ActivityThread.access$800(ActivityThread.java:135)
at at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at at android.os.Handler.dispatchMessage(Handler.java:102)
at at android.os.Looper.loop(Looper.java:136)
at at android.app.ActivityThread.main(ActivityThread.java:5017)
at at java.lang.reflect.Method.invokeNative(Native Method)
at at java.lang.reflect.Method.invoke(Method.java:515)
at at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at at dalvik.system.NativeStart.main(Native Method)
at Caused by: java.lang.ClassNotFoundException: Didn't find class "Client.Android.TimePreference" on path: DexPathList[[zip file "/data/app/Client.Android-1.apk"],nativeLibraryDirectories=[/data/app-lib/Client.Android-1, /vendor/lib, /system/lib]]
at at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
at at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
at at android.preference.GenericInflater.createItem(GenericInflater.java:375)
at at android.preference.GenericInflater.createItemFromTag(GenericInflater.java:430)
at ... 22 more

These are the default attributes available (You can also view inherited attributes by expanding the Inherited XML Attributes block in the android docs for DialogPreference):
android:dialogIcon - The icon for the dialog.
android:dialogLayout - A layout to be used as the content View for the dialog.
android:dialogMessage - The message in the dialog.
android:dialogTitle - The title in the dialog.
android:negativeButtonText - The negative button text for the dialog.
android:positiveButtonText - The positive button text for the dialog.
So in order to use your own attributes you need to create your own Resource file where you define Stylables for your DialogPreference like:
Resource\Values\MyTimePreferenceAttrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyTimePreference">
<attr name="defaultValue" format="string"/>
</declare-styleable>
</resources>
Then in your AXML layout where you create your TimePreference view you need to add a namespace so that they can be resolved:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:my="http://schemas.android.com/apk/res-auto" >
<PreferenceCategory android:title="#string/pref_foo" >
...
<Client.Android.TimePreference
my:defaultValue="12:00" />
...
</PreferenceCategory>
</PreferenceScreen>
Then in your constructor of TimePreference you can get the value with something like:
var ta = context.ObtainStyledAttributes(attrs, Resource.Styleable.MyTimePreference);
var defaultValue = ta.GetString(Resource.Styleable.MyTimePreference_defaultValue);
ta.Recycle();
You also might have a problem with using capitalized namespace in your XML layout. However the classname stays Capitalized, so:
<client.android.TimePreference
...

Related

The type initializer for Test.Program threw an exception

In a .net5.0 project I'm trying to read all mails from txt file, it worked half an hour ago but suddenly when I changed some names for better understanding it stoped working.
I read the txt file location from app.config file and this is the config:
[![enter image description here][1]][1]
The key Im reading is LokacijaExportanihMailAdresa.
This is the key in app.config;
<add key="LokacijaExportanihMailAdresa" value="txt_docs\Mailovi.txt"
This is the code with which im trying to read the txt file:
class Program
{
public static int i = 0;
public static Timer aTimer = new Timer(Int32.Parse(ConfigurationManager.AppSettings.Get("VrijemeUMiliSekundama")));
public static string lokacijaMailova = ConfigurationManager.AppSettings.Get("LokacijaExportanihMailAdresa");
public static string posiljatelj = ConfigurationManager.AppSettings.Get("Posiljatelj");
public static string subjekt = ConfigurationManager.AppSettings.Get("Predmet");
public static string putanjaDoPoruke = ConfigurationManager.AppSettings.Get("Poruka");
public static int imaPrivitak = Int32.Parse(ConfigurationManager.AppSettings.Get("ImaAttachment"));
public static string putanjaDoPrivitka = ConfigurationManager.AppSettings.Get("Privitak");
public static string smtpServer = ConfigurationManager.AppSettings.Get("SmtpServer");
static void Main(string[] args)
{
var logger = NLog.LogManager.GetCurrentClassLogger();
logger.Info("Aplikacija je pokrenuta");
var mailovi = File.ReadAllLines(lokacijaMailova);
aTimer.Elapsed += (sender, e) => OnTimedEvent(sender, e, logger, mailovi, i++);
aTimer.Start();
Console.ReadKey();
}
}
This is the Error:
2021-11-09 13:23:01.6441|Error|MailServis.Program|System.TypeInitializationException: The type initializer for 'MailServis.Program' threw an exception.
---> System.ArgumentNullException: Value cannot be null. (Parameter 's')
at System.Int32.Parse(String s)
at MailServis.Program..cctor() in C:\Users\djcumbaj\source\repos\MailServis\Program.cs:line 21
--- End of inner exception stack trace ---
at MailServis.Program.Main(String[] args) in C:\Users\djcumbaj\source\repos\MailServis\Program.cs:line 32 |
But after I put the path directly in File.ReadAllLines it reads the file but the next thing that happens the Timer throws the same exception when i mean the same it's exactly the same.
Thank you in advance.
You call ConfigurationManager.AppSettings.Get("ImaAttachment") but you have ImaPrivitak in the appSettings.

How to close a IWpfTextView based on a condition from the IWpfTextViewCreationListener - VsTextViewCreated

I have a class which listens to the IWpfTextViewCreationListener
using System.ComponentModel.Composition;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Editor;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.TextManager.Interop;
using Microsoft.VisualStudio.Utilities;
using Microsoft.VisualStudio.OLE.Interop;
namespace GoToSequence
{
[Export(typeof(IVsTextViewCreationListener))]
[ContentType("Code")]
[TextViewRole(PredefinedTextViewRoles.Editable)]
internal class GoToSequenceEditorCreationListener : IVsTextViewCreationListener
{
[Import(typeof(IVsEditorAdaptersFactoryService))]
internal IVsEditorAdaptersFactoryService editorFactory = null;
public void VsTextViewCreated(IVsTextView textViewAdapter)
{
IWpfTextView textView = editorFactory.GetWpfTextView(textViewAdapter);
if (textView == null)
return;
AddCommandFilter(textViewAdapter, new GoToSequenceCommandHandler(textView, textViewAdapter));
}
void AddCommandFilter(IVsTextView viewAdapter, GoToSequenceCommandHandler commandFilter)
{
if (commandFilter.m_added == false)
{
//get the view adapter from the editor factory
IOleCommandTarget next;
int hr = viewAdapter.AddCommandFilter(commandFilter, out next);
if (hr == VSConstants.S_OK)
{
commandFilter.m_added = true;
//you'll need the next target for Exec and QueryStatus
if (next != null)
commandFilter.m_nextTarget = next;
}
}
}
}
}
In the function - VsTextViewCreated, based on a certain condition I want to close the textview.
If (condition == null)
IWpfTextView.Close()
However after doing this I get the following error
System.ObjectDisposedException was unhandled Message: An unhandled
exception of type 'System.ObjectDisposedException' occurred in
Microsoft.VisualStudio.Platform.VSEditor.dll Additional information:
Cannot access a disposed object.
I also tried
if(condition == null)
IVsTextView.CloseView()
but this also did not help. What could be the correct way to close the textview programmatically?
Okay... I was able to resolve the above...
var dte2 = (EnvDTE80.DTE2)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(Microsoft.VisualStudio.Shell.Interop.SDTE));
Microsoft.VisualStudio.OLE.Interop.IServiceProvider sp = (Microsoft.VisualStudio.OLE.Interop.IServiceProvider)dte2;
Microsoft.VisualStudio.Shell.ServiceProvider serviceProvider = new Microsoft.VisualStudio.Shell.ServiceProvider(sp);
Microsoft.VisualStudio.Shell.Interop.IVsUIHierarchy uiHierarchy;
uint itemID;
Microsoft.VisualStudio.Shell.Interop.IVsWindowFrame windowFrame;
Microsoft.VisualStudio.Shell.VsShellUtilities.IsDocumentOpen(serviceProvider, _iTextDocument.FilePath, Guid.Empty, out uiHierarchy, out itemID, out windowFrame);
windowFrame.CloseFrame((uint)__FRAMECLOSE.FRAMECLOSE_NoSave);
But, I still wonder why doesn't the IWpfTextView.Close() or IVSTextView.CloseView() do not work...

MonoDevelop Addin for NaCl using 'ProjectServiceExtension'

Hi all i'm trying to make a MonoDevelop addin that I can use to compile out Mono for NaCl projects... but i'm getting a null ref error and can't find enough information to figure out whats going wrong.
The null ref happens when I try to create a project from my Addin in MonoDevelop.
All resources are set to build as 'EmbeddedResource'.
Builder.cs:
using System;
using MonoDevelop.Projects;
using MonoDevelop.Core;
namespace MonoDevelop.MonoNaCl
{
public class Builder : ProjectServiceExtension
{
protected override BuildResult Build (IProgressMonitor monitor, SolutionEntityItem item, ConfigurationSelector configuration)
{
Console.WriteLine("Yahoo Build");
return base.Build (monitor, item, configuration);
}
protected override void Execute (IProgressMonitor monitor, SolutionEntityItem item, ExecutionContext context, ConfigurationSelector configuration)
{
Console.WriteLine("Yahoo Execute");
base.Execute (monitor, item, context, configuration);
}
}
}
MonoDevelop.MonoNaCl.addin.xml:
NOTE: I'm really not clear on the 'Extension's I should use and think the issue is in there.
<Addin namespace = "MonoDevelop"
id = "MonoNaCl"
name = "Mono for NaCl"
author = "Andrew Witte"
copyright = "BSD"
url = "http://www.URL.com"
description = "Support for developing MonoNaCl applications."
category = "NaCl Development"
version = "1.0">
<Dependencies>
<Addin id="Ide" version="3.0" />
<Addin id="Core" version="3.0" />
</Dependencies>
<Extension path = "/MonoDevelop/Ide/ProjectTemplates">
<ProjectTemplate id = "MonoNaClProject" resource = "MonoNaCl.xpt.xml"/>
</Extension>
<Extension path = "/MonoDevelop/ProjectModel/ProjectServiceExtensions">
<Class class = "MonoDevelop.MonoNaCl.Builder"/>
</Extension>
<!--<Extension path = "/MonoDevelop/ProjectModel/MSBuildItemTypes">
<SolutionItem type="MonoDevelop.MonoNaCl.Builder" extension="csproj" guid="{49DFC40D-C27A-4230-A637-8D9669269586}"/>
</Extension>-->
<Extension path="/MonoDevelop/ProjectModel/SerializableClasses">
<DataType class="MonoDevelop.MonoNaCl.Builde" />
</Extension>
</Addin>
MonoNaCl.xpt.xml:
<?xml version="1.0"?>
<Template originator = "Andrew Witte">
<TemplateConfiguration>
<_Name>MonoNaCl Project</_Name>
<_Category>C#/MonoNaCl</_Category>
<LanguageName>C#</LanguageName>
<_Description>Creates a MonoNaCl project.</_Description>
</TemplateConfiguration>
<Combine name = "${ProjectName}" directory = ".">
<Options>
<StartupProject>${ProjectName}</StartupProject>
</Options>
<Project name = "${ProjectName}" directory = "." type = "MonoNaCl">
<Options/>
</Project>
</Combine>
</Template>
And here is the Error after trying to create a project:
System.NullReferenceException: Object reference not set to an instance of an object
at MonoDevelop.Projects.SolutionFolderItemCollection.OnItemAdded (MonoDevelop.Projects.SolutionItem item) [0x0000b] in /Users/builder/data/lanes/monodevelop-mac-3.0.1/6642975f/source/monodevelop/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolderItemCollection.cs:59
at MonoDevelop.Projects.ItemCollection`1[MonoDevelop.Projects.SolutionItem].InsertItem (Int32 index, MonoDevelop.Projects.SolutionItem item) [0x00008] in /Users/builder/data/lanes/monodevelop-mac-3.0.1/6642975f/source/monodevelop/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ItemCollection.cs:39
at System.Collections.ObjectModel.Collection`1[MonoDevelop.Projects.SolutionItem].Add (MonoDevelop.Projects.SolutionItem item) [0x00000] in <filename unknown>:0
at MonoDevelop.Ide.Templates.SolutionDescriptor.CreateEntry (MonoDevelop.Projects.ProjectCreateInformation projectCreateInformation, System.String defaultLanguage) [0x0026c] in /Users/builder/data/lanes/monodevelop-mac-3.0.1/6642975f/source/monodevelop/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/SolutionDescriptor.cs:162
at MonoDevelop.Ide.Templates.ProjectTemplate.CreateWorkspaceItem (MonoDevelop.Projects.ProjectCreateInformation cInfo) [0x00000] in /Users/builder/data/lanes/monodevelop-mac-3.0.1/6642975f/source/monodevelop/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/ProjectTemplate.cs:232
at MonoDevelop.Ide.Projects.NewProjectDialog.CreateProject () [0x001ef] in /Users/builder/data/lanes/monodevelop-mac-3.0.1/6642975f/source/monodevelop/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectDialog.cs:432
Remove the type="MonoNaCl" attribute definition in the Project element.
You don't have to set the project type, unless you are defining your own Project subclass.

C# Storing multiple Items in multiple arrays for comparison

I have an application that reads File names and their equivalent Hash codes from an XML(After i have created the XML using the same application) and What i would like it to do is compare one XML (the files and their hash codes) to another XML(With possibly different files and hash codes). I'm trying to create a compare function so that i can compare the file names, first, between the two XMLs and then compare the Hash codes if the files exists in both XMLs.
(to help understand what im trying to achieve basically i have 2 listboxes next to each other, one for each of the xmls. Once i compare them i want both listboxes populated with all the file names but not the hashcodes and then to mark them in different colors depending if they are the same file, same file but different content or the file does not exist at all in the other XML.)
I'm struggling to find a way to store the file names and their hash codes.
Code(I am using a C++ Dll i created to do some of the work):
private String[] ProjOne()
{
//Intialize the functions in the DLL
DllTest.Funtions Functions = new DllTest.Funtions();
//Set the location where the XMLs can be found
String Directory = "C:\\Users\\brandonm\\Desktop\\Backup\\XML\\";
//Get and set the number of items in the directory
int NumFiles = Functions.GetNumFiles(Directory);
//Create a search string to be used to determine the fullpath name of the file
//selected from the combobox
String SelectedFile = comboBox1.SelectedItem.ToString();
String SearchString = "*" + SelectedFile + "*.XML";
//Get and set the TC that will be used to get the filenames and hashcodes
int SelectedTC = int.Parse(comboBox2.SelectedItem.ToString());
//Get and set an array containing a full path structure to the item selected from
//the combobox using the search string created earlier. Get files returns an array
//thus needs to be stored in an array
String[] FullPaths = new String[NumFiles];
FullPaths = System.IO.Directory.GetFiles("C:\\Users\\brandonm\\Desktop\\Backup\\XML", SearchString, System.IO.SearchOption.AllDirectories);
int number = FullPaths.GetLength(0);
// The number of items in the XML ie. Number of Filenames in a particular TC
int NumXMLItems = NumXMLItemsListOne();
// Initialize the array that will hold the Filenames and their equivalent Hashcodes
String[] FileNames = new String[NumXMLItems];
String[] HashCode = new String[NumXMLItems];
String[,] ProjectOne = new String[HashCode.Length, HashCode.Length];
//Itteration through the all the XMLs in the location to add the current items into their arrays
for (int x = 0; x < NumFiles; x++)
{
String FullPath = FullPaths[x];
XPathNavigator Root = new XPathDocument(FullPath).CreateNavigator();
foreach (XPathNavigator Cycle in Root.Select(String.Format(#"//TestCycle[#Number = '{0}']", SelectedTC)))
{
foreach (XPathNavigator Nav in Cycle.Select(#"Files/FileName/#File"))
{
int y = 0;
FileNames[y] = Nav.Value;
y = y + 1;
}
foreach (XPathNavigator Nav in Cycle.Select(#"Files/HashCode/#Code"))
{
int z = 0;
HashCode[z] = Nav.Value;
z = z + 1;
}
}
}
return FileNames;
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<Projects>
<Project Name="tfasdtyf">
<TestCycle Number="2387468">
<Files>
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" />
<HashCode Code="0E-C5-03-AD-CC-21-62-49-D9-36-3F-C4-F1-17-BC-11" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
<HashCode Code="60-46-A3-6F-82-E4-0A-00-2A-60-83-47-B2-16-F3-24" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
</Files>
</TestCycle>
</Project>
<Project Name="tfasdtyf">
<TestCycle Number="23423">
<Files>
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" />
<HashCode Code="0E-C5-03-AD-CC-21-62-49-D9-36-3F-C4-F1-17-BC-11" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
<HashCode Code="60-46-A3-6F-82-E4-0A-00-2A-60-83-47-B2-16-F3-24" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
</Files>
</TestCycle>
</Project>
<Project Name="tfasdtyf">
<TestCycle Number="1112">
<Files>
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" />
<HashCode Code="0E-C5-03-AD-CC-21-62-49-D9-36-3F-C4-F1-17-BC-11" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
<HashCode Code="60-46-A3-6F-82-E4-0A-00-2A-60-83-47-B2-16-F3-24" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
</Files>
</TestCycle>
</Project>
<Project Name="tfasdtyf">
<TestCycle Number="999">
<Files>
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" />
<HashCode Code="0E-C5-03-AD-CC-21-62-49-D9-36-3F-C4-F1-17-BC-11" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
<HashCode Code="60-46-A3-6F-82-E4-0A-00-2A-60-83-47-B2-16-F3-24" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
</Files>
</TestCycle>
</Project>
<Project Name="tfasdtyf">
<TestCycle Number="34534">
<Files>
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" />
<HashCode Code="0E-C5-03-AD-CC-21-62-49-D9-36-3F-C4-F1-17-BC-11" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
<HashCode Code="60-46-A3-6F-82-E4-0A-00-2A-60-83-47-B2-16-F3-24" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
</Files>
</TestCycle>
</Project>
<Project Name="Music">
<TestCycle Number="12312">
<Files>
<FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\01 A1 Shut Ya Mouth.mp3" />
<HashCode Code="3E-92-80-93-D5-64-19-16-26-8D-39-2A-C7-0B-C8-EB" />
<FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\01 A1 Snake Eater.mp3" />
<HashCode Code="8B-DF-19-AE-87-52-64-2E-85-CF-57-4B-85-4D-CC-E9" />
<FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\01 A1 Stuck in the System.mp3" />
<HashCode Code="6A-30-A7-53-FF-29-A5-DF-6D-24-DF-41-74-EE-06-4D" />
<FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\01 Martin Solveig - Hello (Featuring Dragonette).mp3" />
<HashCode Code="93-90-A3-9C-BE-81-63-03-D7-96-1F-72-E4-ED-2D-32" />
<FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\01 Stimming - Funkworm.mp3" />
<HashCode Code="8F-E1-7A-F1-B7-80-C6-2F-DC-34-FD-82-A0-DA-35-5E" />
<FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\1. Downlink - Ignition.mp3" />
<HashCode Code="3D-89-B3-C2-73-A6-A0-85-02-C0-B4-F9-C8-09-14-C7" />
<FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\02 B1 Psychedelic Runway.mp3" />
<HashCode Code="00-72-5C-CE-25-73-98-31-69-71-68-48-31-A1-A3-5A" />
<FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\02 B1 Rapture.mp3" />
<HashCode Code="1E-A6-53-07-10-FD-A3-4C-EF-D6-92-7F-CE-97-88-6E" />
<FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\02_Digital-Controller.mp3" />
<HashCode Code="94-E0-CA-5F-2B-D2-56-7B-AF-2E-04-50-58-38-4D-B4" />
<FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\2. Downlink - Gamma Ray.mp3" />
<HashCode Code="3C-7A-76-AD-A6-2C-D1-7E-61-24-C0-40-BD-A7-A9-41" />
</Files>
</TestCycle>
</Project>
</Projects>
I currently have another function identical to the one above so one for each listbox the only difference is the file and the testcyle number which determines where in the XML they will retrieve their files and hash codes. They store them in 4 separate arrays, 2 arrays per function. But obviously my function cannot return two arrays so it is currently only return the one.
2D arrays confuse me a lot and im not sure how i would get the information i need out of them when it comes down to the comparing i need to do. Can anyone direct me to a better way of doing this?
I dont want to really make 4 functions like the one above for the each set of filenames and then each set of hashcodes. But i'm still a beginner so maybe that is my best option?
It's better not to duplicate the function. You want to make a single function that can be used in all of your cases here.
As for storing the filenames and hashcodes, .NET has a lot of useful collection classes you can use. For example, you could use a Dictionary<string, string> like this:
Dictionary<string, string> dictionary = new Dictionary<string, string>();
for (int i = 0; i < NumFiles; i++)
{
dictionary.Add(FileNames[i], HashCode[i]);
}
The above code you could put right before your return statement in the function you provided. Then return the dictionary. Of course, you could make the entire function shorter by storing them directly in the dictionary, but I'll leave that for you to decide.
Now, wherever this function is called from, you might need to loop through this dictionary. Here's a way to do that:
foreach (var pair in dictionary)
{
string filename = pair.Key;
string hashcode = pair.Value;
// Do whatever you want with them here
}
No doubt there are other ways to do what you want. I am not completely sure what your overall goal is. You should experiment with other generic collections too, such as List<T>.
If HashCode belongs to a File, why isn't it a sub-element/attribute of it? It would make it way easier to parse.
Since you create the file, I'd create the structure like:
<Project Name="tfasdtyf">
<TestCycle Number="23423">
<Files>
<File Name="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" HashCode="0E-C5-03-AD-CC-21-62-49-D9-36-3F-C4-F1-17-BC-11" />
<File Name="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" HashCode="60-46-A3-6F-82-E4-0A-00-2A-60-83-47-B2-16-F3-24" />
<File Name="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" HashCode="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
</Files>
</TestCycle>
</Project>
Then with some XElement magic, you could use:
public class Project
{
XElement self;
public Project(XElement project)
{
self = project;
}
public TestCycle TestCycle
{
get
{
// If there are more than one TestCycle per project, you may end
// up creating something similar to TestCycle.Files (see TestCycle class below)
XElement testCycle = self.Element("TestCycle");
if(null == testCycle)
self.Add(testCycle = new XElement("TestCycle"));
return new TestCycle(testCycle);
}
}
public string Name
{
get { return return self.GetString("Name", string.Empty, ATTRIBUTE); }
set { self.Set("Name", value, ATTRIBUTE); } // see Set Extension method below
}
public static IEnumerable<Project> Load(string filename)
{
return XElement.Load(filename)).Elements("Project").Select(xp => new Project(xp));
}
}
public class TestCycle
{
XElement self;
public TestCycle(XElement testCycle)
{
self = testCycle;
}
private XElement XFiles
{
get
{
XElement files = self.Element("Files");
if(null == files)
self.Add(files = new XElement("Files"));
return files;
}
}
public IEnumerable<FileHash> Files
{
get
{
return XFiles.Elements("File").Select(xf => new FileHash(xf));
}
}
public int Number
{
get { return self.GetInt("Number", 0, ATTRIBUTE); }
set { self.Set("Number", value, ATTRIBUTE); } // see Set Extension method below
}
public FileHash AddFile(string name, string hashCode)
{
FileHash file = Files.FirstOrDefault(xf => xf.Name == name);
if(null != file)
file.self.Remove(); // replacing (but could throw an exception saying already exists instead)
XElement xFile = new XElement("File");
self.Add(xFile);
file = new FileHash(xFile)
{
Name = name,
HashCode = hashCode
};
return file;
}
}
public class FileHash
{
internal XElement self;
public FileHash(XElement fileHash)
{
self = fileHash;
}
public string Name
{
get { return self.GetString("Name", string.Empty, ATTRIBUTE); }
set { self.Set("Name", value, ATTRIBUTE); } // see Set Extension method below
}
public string HashCode
{
get { return return self.GetString("HashCode", string.Empty, ATTRIBUTE); }
set { self.Set("HashCode", value, ATTRIBUTE); } // see Set Extension method below
}
}
Extension methods:
public static XElementExtensions
{
public const bool ATTRIBUTE = true;
public const bool ELEMENT = false;
public const bool? BOTH = null;
public void Set(this XElement self, string name, object value, bool isAttribute)
{
string sValue = value.ToString();
XElement eValue = self.Element(name);
XAttribute aValue = self.Attribute(name);
if(null != eValue)
eValue.ReplaceWith(new XElement(name, sValue));
else if(null != aValue)
aValue.ReplaceWith(new XAttribute(name, sValue));
else if(isAttribute)
self.Add(new XAttribute(name, sValue));
else
self.Add(new XElement(name, sValue));
}
public string GetString(this XElement self, string name, string #default, bool? isAttribute)
{
XAttribute aValue = self.Attribute(name);
XElement eValue = self.Element(name);
if(null == isAttribute) // try both
{
if(null != aValue) return (string)aValue;
if(null != eValue) return (string)eValue;
return #default;
}
if(isAttribute && null != aValue)
return (string)aValue;
if(!isAttribute && null != eValue)
return (string)eValue);
return #default;
}
public int GetInt(this XElement self, string name, int #default, bool? isAttribute)
{
return Convert
.ToInt32(GetString(self, name, null, isAttribute) ?? #default.ToString());
}
}
Then you can use the code like:
Project[] projects = Project.Load(filename).ToArray();
foreach(Project project in projects)
{
Console.WriteLine("Project: " + project.Name);
Console.WriteLine("TestCycle: " + project.TestCycle.Number.ToString());
Console.WriteLine("Files:");
foreach(FileHash file in project.TestCycle.Files)
Console.WriteLine(string.Format(" Name: {0}, HashCode: {1}", file.Name, file.HashCode));
}
Or for your application, to compare two xml files:
var fileA = Project.Load(fileAname);
var fileB = Project.Load(fileBname);
I'm not quite sure how you mean, all the files, but I'll attempt it.
File[] filesA = fileA.SelectMany(project => project.TestCycle.Files).ToArray();
File[] filesB = fileB.SelectMany(project => project.TestCycle.Files).ToArray();
Using these Extension Methods:
public static IEnumerable<TSource> Except<TSource>
(
this IEnumerable<TSource> first,
IEnumerable<TSource> second,
Func<TSource, TSource, bool> comparer
)
{
return first.Except(second, new LambdaComparer<TSource>(comparer));
}
public static IEnumerable<TSource> Intersect<TSource>
(
this IEnumerable<TSource> first,
IEnumerable<TSource> second,
Func<TSource, TSource, bool> comparer
)
{
return first.Intersect(second, new LambdaComparer<TSource>(comparer));
}
And the LambdaComparer class:
public class LambdaComparer<T> : IEqualityComparer<T>
{
private readonly Func<T, T, bool> equals;
private readonly Func<T, int> getHashCode;
public LambdaComparer(Func<T, T, bool> lambdaComparer) :
this(lambdaComparer, o => o.GetHashCode())
{
}
public LambdaComparer(Func<T, T, bool> lambdaComparer, Func<T, int> lambdaHash)
{
if (lambdaComparer == null)
throw new ArgumentNullException("lambdaComparer");
if (lambdaHash == null)
throw new ArgumentNullException("lambdaHash");
equals = lambdaComparer;
getHashCode = lambdaHash;
}
public bool Equals(T x, T y)
{
return equals(x, y);
}
public int GetHashCode(T obj)
{
return getHashCode(obj);
}
}
File[] filesInA_butNotInB = filesA.Except(filesB, (a,b) => a.Name == b.Name).ToArray();
File[] filesInBoth = filesA.Intersect(filesB, (a,b) => a.Name == b.Name).ToArray();
File[] filesInBoth_butDifferentHash = FilesA.Intersect(filesB, (a,b) => a.Name == b.Name && a.HashCode != b.HashCode).ToArray();
That should "get you started" ...
PS: I wrote (most of) this all by hand, not via compiler so there are probably some typo's that the compiler will catch.
PS: Also, all the .ToArray()'s are just because File[] is easier to read than IEnumerable<File>. It is easier to read but about the same typing either way.
PSS: I hope you find this useful. I love the Xml Linq way of handling things, so it was fun writing this out.

Looking for a HTTPHandler to modify pages on the fly to point to a CDN

What I'm trying to do is create (or perhaps one already exists) a HTTPHandler that will filter the HTML generated ASP.NET to use the content delivery network (CDN). For example, I want to rewrite references such as this:
/Portals/_default/default.css
to
http://cdn.example.com/Portals/_default/default.css
I'm perfectly happy using RegEx to match the initial strings. Such a regex patterns might be:
href=['"](/Portals/.+\.css)
or
src=['"](/Portals/.+\.(css|gif|jpg|jpeg))
This is a dotnetnuke site and I don't really have control over all the HTML generated so that's why I want to do it with an HTTPHandler. That way the changes can be done post-page generation.
You could write a response filter which can be registered in a custom HTTP module and which will modify the generated HTML of all pages running the regex you showed.
For example:
public class CdnFilter : MemoryStream
{
private readonly Stream _outputStream;
public CdnFilter(Stream outputStream)
{
_outputStream = outputStream;
}
public override void Write(byte[] buffer, int offset, int count)
{
var contentInBuffer = Encoding.UTF8.GetString(buffer);
contentInBuffer = Regex.Replace(
contentInBuffer,
#"href=(['""])(/Portals/.+\.css)",
m => string.Format("href={0}http://cdn.example.com{1}", m.Groups[1].Value, m.Groups[2].Value)
);
contentInBuffer = Regex.Replace(
contentInBuffer,
#"src=(['""])(/Portals/.+\.(css|gif|jpg|jpeg))",
m => string.Format("href={0}http://cdn.example.com{1}", m.Groups[1].Value, m.Groups[2].Value)
);
_outputStream.Write(Encoding.UTF8.GetBytes(contentInBuffer), offset, Encoding.UTF8.GetByteCount(contentInBuffer));
}
}
and then write a module:
public class CdnModule : IHttpModule
{
void IHttpModule.Dispose()
{
}
void IHttpModule.Init(HttpApplication context)
{
context.ReleaseRequestState += new EventHandler(context_ReleaseRequestState);
}
void context_ReleaseRequestState(object sender, EventArgs e)
{
HttpContext.Current.Response.Filter = new CdnFilter(HttpContext.Current.Response.Filter);
}
}
and register in web.config:
<httpModules>
<add name="CdnModule" type="MyApp.CdnModule, MyApp"/>
</httpModules>

Categories

Resources