Using base View Model Class with GalaSoft MVVM Light - mvvm

I am creating a project using WPF and MVVM-Light library from GalaSoft. I will have a base abstract View Model class, which will be used by all other View Model classes implemented. There I will have MVVM-Light base class as my base class. However, inside this base class, when I try to use RaisePropertyChanged function I get the following error:
An object reference is required for the non-static field, method, or property 'GalaSoft.MvvmLight.ViewModelBase.RaisePropertyChanged(string)'
The code will look like this:
AnalysisViewModelBase : ViewModelBase
{
public const string TagDescriptionStringListPropertyName = "TagDescriptionStringList";
protected static List<string> m_tagDescriptionStringList;
public static List<string> TagDescriptionStringList
{
get
{ return m_tagDescriptionStringList; }
set
{
if (m_tagDescriptionStringList == value)
return;
m_tagDescriptionStringList = value;
RaisePropertyChanged(TagDescriptionStringListPropertyName);
}
}
protected AnalysisViewModelBase()
{
m_tagDescriptionStringList = new List<string>();
m_tagDescriptionStringList.AddRange(new string[] { "North Position", "East Position", "Depth" });
}
}
AnotherViewModel : AnalysisViewModelBase
{ ... }
Could anyone please help me understand what is wrong with my RaiseProperyChanged function?

You are trying to access a Non Static Method From a Static Method... It does not have access to this value, you have to make your method non static.
here is a web page which explains about static methods if you want to have a better understanding of why you can't do what you are trying to do.
Link

You simply must declare your property "Tax DescriptionStringList " as non static. Since the backingfield (m_tagDescriptionStringList) is static it remains the same thing. Make this :
class AnalysisViewModelBase : ViewModelBase
{
public const string TagDescriptionStringListPropertyName = "TagDescriptionStringList";
protected static List<string> m_tagDescriptionStringList;
public List<string> TagDescriptionStringList
{
get
{ return m_tagDescriptionStringList; }
set
{
if (m_tagDescriptionStringList == value)
return;
m_tagDescriptionStringList = value;
RaisePropertyChanged(TagDescriptionStringListPropertyName);
}
}
protected AnalysisViewModelBase()
{
m_tagDescriptionStringList = new List<string>();
m_tagDescriptionStringList.AddRange(new string[] { "North Position", "East Position", "Depth" });
}
}
AnotherViewModel : AnalysisViewModelBase
{ ... }
If it is absolutely necessary to keep the property as a static property in this case, here is a solution: raise the property changes (using RaisePropertyChanged("TagDescriptionStringList")) when it happens, as I indicated in the code below
class AnalysisViewModelBase : ViewModelBase
{
public const string TagDescriptionStringListPropertyName = "TagDescriptionStringList";
protected static List<string> m_tagDescriptionStringList;
public static List<string> TagDescriptionStringList
{
get
{ return m_tagDescriptionStringList; }
set
{
if (m_tagDescriptionStringList != value)
{
m_tagDescriptionStringList = value;
}
}
}
protected AnalysisViewModelBase()
{
m_tagDescriptionStringList = new List<string>();
m_tagDescriptionStringList.AddRange(new string[] { "North Position", "East Position", "Depth" });
RaisePropertyChanged("TagDescriptionStringList");
}
}
AnotherViewModel : AnalysisViewModelBase
{ ... }

Related

how to search any keyword from string using jfce AutoCompleteField

I have swt text where in I have written like "new AutoCompleteField (textSearch,new TextContentProvider(), searchList); it works but it finds the strings start with expression. I want to create my own proposal provider where i can write something if my string contains any keyword, i should get autoComplete popup.
You can't use the existing AutoCompleteField for this since you need to change the content proposal provider.
A suitable IContentProposalProvider would be something like:
public class AnyPositionContentProposalProvider implements IContentProposalProvider
{
private final String [] proposals;
public AnyPositionContentProposalProvider(String [] theProposals)
{
proposals = theProposals;
}
#Override
public IContentProposal [] getProposals(String contents, int position)
{
List<IContentProposal> result = new ArrayList<>();
for (String proposal : proposals) {
if (proposal.contains(contents)) {
result.add(new ContentProposal(proposal));
}
}
return result.toArray(new IContentProposal [result.size()]);
}
}
The following methods set this up to work like AutoCompleteField:
// Installs on a Text control
public static void installAnyPositionMatch(Text control, String [] proposals)
{
installAnyPositionMatch(control, new TextContentAdapter(), proposals);
}
// Install on any control with a content adapter
public static void installAnyPositionMatch(Control control, IControlContentAdapter controlContentAdapter, String [] proposals)
{
IContentProposalProvider proposalProvider = new AnyPositionContentProposalProvider(proposals);
ContentProposalAdapter adapter = new ContentProposalAdapter(control, controlContentAdapter, proposalProvider, null, null);
adapter.setPropagateKeys(true);
adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
}

GWT multiple Activities/Places with one Token

My Site has on the left a GWT-Tree. In the center is a GWT-TabBar.
Both parts are implemented as Views/Activities/Places. I have two tokenizer: "m" for the tree and "t" for the tabs.
If I visit one place (goTo()) only this place will be used to generate the history token. But I would like to see this: <page>#m:sub/sub/sub;t:map
I actually thought that the hole idea of activities&places. I don't see the point to have multiple tokenizer, when only one tokenizer can provide a token at once.
You cannot display two different tokens #m: and #t: at the same time as you cannot be in two places at the same time.
So if both tabs and tree are displaying at the same time, then the state of both must be stored at once in the same place.
This is more or less what you need.
public class ExamplePlace extends Place {
public String treePosition = "/";
public int tabIndex = 0;
public ExamplePlace() {
super();
}
public ExamplePlace(String treePosition, int tabIndex) {
this.treePosition = treePosition;
this.tabIndex = tabIndex;
}
#Prefix("overview")
public static class Tokenizer implements PlaceTokenizer<ExamplePlace> {
/**
* parse token to get state
*
*/
#Override
public ExamplePlace getPlace(String token) {
String treePosition = "";
int tabIndex = 0;
String[] states = token.split(";");
for (String state : states) {
String[] mapping = state.split("=");
if (mapping.length == 2) {
if ("t".equals(mapping[0])) {
treePosition = mapping[1];
}
if ("m".equals(mapping[0])) {
try {
tabIndex = Integer.valueOf(mapping[1]);
} catch (Throwable e) {
}
}
}
}
return new ExamplePlace(treePosition, tabIndex);
}
/**
* store state in token
*
*/
#Override
public String getToken(ExamplePlace place) {
StringBuffer sb = new StringBuffer();
if (place.getTreePosition()!=null) {
sb.append("t").append("=").append(place.getTreePosition());
sb.append(";");
}
sb.append("m=").append(place.getTabIndex());
return sb.toString();
}
}
public String getTreePosition() {
return treePosition;
}
public void setTreePosition(String treePosition) {
this.treePosition = treePosition;
}
public int getTabIndex() {
return tabIndex;
}
public void setTabIndex(int tabIndex) {
this.tabIndex = tabIndex;
}
}
This will give you URLs that look like ;
index.html#overview:t=/subtree/subtree/leaf;m=2
You might run in trouble with the forward slashes in the token, not sure. Change them to some other character if necessary;
The activity receives the incoming place and inject the state into the view;

SuggestBox override addSelectionHandler

I have a custom Oracle with Objects to pass to the SuggestBox. Then I need get back a object when it's selected from de SuggestBox.
public HandlerRegistration addSelectionHandler(SelectionHandler<SuggestOracle.Suggestion> handler)
The problem is that I don't have Suggestion. I have "CustomSuggestion". I read de API and I try to write a Custom SuggestBox implementing the interface HasSelectionHandlers but I can't because the SuggestBox have a implementation of the interface. I get the error:
The interface HasSelectionHandlers cannot be implemented more than once with different arguments: HasSelectionHandlers<SuggestOracle.Suggestion> and HasSelectionHandlers<CustomSuggestion>
Can you help me? Sorry for my bad english.
Not sure I understand your problem. Have a look at the following example (really basic but you should get an idea on how to deal with custom suggestions). Hope that helps:
public void onModuleLoad() {
SuggestBox box = new SuggestBox(new CustomOracle<CustomSuggestion>());
box.addSelectionHandler(new SelectionHandler<SuggestOracle.Suggestion>() {
#Override
public void onSelection(SelectionEvent<Suggestion> event) {
String value = ((CustomSuggestion) event.getSelectedItem()).fSomeOtherValue;
Window.alert(value);
}
});
RootPanel.get().add(box);
}
private class CustomOracle<CustomSuggestion> extends SuggestOracle {
private LinkedList<Starter.CustomSuggestion> fStore;
public CustomOracle() {
fStore = new LinkedList<Starter.CustomSuggestion>();
fStore.add(new Starter.CustomSuggestion("2", "two", "foo"));
fStore.add(new Starter.CustomSuggestion("22", "twenty-two", "bar"));
fStore.add(new Starter.CustomSuggestion("222", "two-hundred twenty-two", "w000t"));
}
#Override
public void requestSuggestions(Request request, Callback callback) {
String query = request.getQuery();
LinkedList<Starter.CustomSuggestion> result = new LinkedList<Starter.CustomSuggestion>();
for (Starter.CustomSuggestion entry : fStore) {
if (entry.fDisplay.contains(query)) {
result.add(entry);
}
}
callback.onSuggestionsReady(request, new Response(result));
}
}
private class CustomSuggestion implements Suggestion {
private String fReplace;
private String fDisplay;
private String fSomeOtherValue;
public CustomSuggestion(String display, String replace, String someOtherValue) {
fDisplay = display;
fReplace = replace;
fSomeOtherValue = someOtherValue;
}
#Override
public String getDisplayString() {
return fDisplay;
}
#Override
public String getReplacementString() {
return fReplace;
}
}

StructureMap InstanceInterceptor not being called

I want to intercept the creation of an instance in SM and I'm trying the following but it's not calling the InstanceInterceptor implementation, does anyone know why?
ForRequestedType<IPublishResources>()
.TheDefault
.Is
.OfConcreteType<PublisherService>()
.InterceptWith(new PublisherServiceInterceptor());
The test code uses the ObjectFactory to create instances, and is shown below:
// Given we have a configure object factory in StructureMap...
ObjectFactory.Configure(x => x.AddRegistry(new StructureMapServiceRegistry()));
// When we request a publisher service...
var publisher = ObjectFactory.GetInstance<IPublishResources>();
Cheers
AWC
I could not reproduce your problem in release 2.5.4. Here is my code.
public interface IPublishResources {}
class PublishResources : IPublishResources {}
public class LoggingInterceptor : InstanceInterceptor
{
//this interceptor is a silly example of one
public object Process(object target, IContext context)
{
Console.WriteLine("Interceptor Called");
return context.GetInstance<PublishResources>();
}
}
public class MyRegistry : Registry
{
public MyRegistry()
{
For<IPublishResources>()
.Use<PublishResources>()
.InterceptWith(new LoggingInterceptor());
}
}
[TestFixture]
public class Structuremap_interception_configuraiton
{
[Test]
public void connecting_implementations()
{
var container = new Container(cfg =>
{
cfg.AddRegistry<MyRegistry>();
});
container.GetInstance<IPublishResources>();
}
}
A question. Do you really need to use an Interceptor here? If you only need to define a factory you can do somethign like this.
public interface IPublishResourcesFactory
{
IPublishResources Create();
}
public class MyRegistry : Registry
{
public MyRegistry()
{
For<IPublishResources>().Use(c =>
{
return c.GetInstance<IPublishResourcesFactory>().Create();
});
//or
For<IPublishResources>().Use(c =>
{
//other object building code.
return new PublishResources();
});
}
}

Refactoring two basic classes

How would you refactor these two classes to abstract out the similarities? An abstract class? Simple inheritance? What would the refactored class(es) look like?
public class LanguageCode
{
/// <summary>
/// Get the lowercase two-character ISO 639-1 language code.
/// </summary>
public readonly string Value;
public LanguageCode(string language)
{
this.Value = new CultureInfo(language).TwoLetterISOLanguageName;
}
public static LanguageCode TryParse(string language)
{
if (language == null)
{
return null;
}
if (language.Length > 2)
{
language = language.Substring(0, 2);
}
try
{
return new LanguageCode(language);
}
catch (ArgumentException)
{
return null;
}
}
}
public class RegionCode
{
/// <summary>
/// Get the uppercase two-character ISO 3166 region/country code.
/// </summary>
public readonly string Value;
public RegionCode(string region)
{
this.Value = new RegionInfo(region).TwoLetterISORegionName;
}
public static RegionCode TryParse(string region)
{
if (region == null)
{
return null;
}
if (region.Length > 2)
{
region = region.Substring(0, 2);
}
try
{
return new RegionCode(region);
}
catch (ArgumentException)
{
return null;
}
}
}
It depends, if they are not going to do much more, then I would probably leave them as is - IMHO factoring out stuff is likely to be more complex, in this case.
Unless you have a strong reason for refactoring (because you are going to add more classes like those in near future) the penalty of changing the design for such a small and contrived example would overcome the gain in maintenance or overhead in this scenario. Anyhow here is a possible design based on generic and lambda expressions.
public class TwoLetterCode<T>
{
private readonly string value;
public TwoLetterCode(string value, Func<string, string> predicate)
{
this.value = predicate(value);
}
public static T TryParse(string value, Func<string, T> predicate)
{
if (value == null)
{
return default(T);
}
if (value.Length > 2)
{
value = value.Substring(0, 2);
}
try
{
return predicate(value);
}
catch (ArgumentException)
{
return default(T);
}
}
public string Value { get { return this.value; } }
}
public class LanguageCode : TwoLetterCode<LanguageCode> {
public LanguageCode(string language)
: base(language, v => new CultureInfo(v).TwoLetterISOLanguageName)
{
}
public static LanguageCode TryParse(string language)
{
return TwoLetterCode<LanguageCode>.TryParse(language, v => new LanguageCode(v));
}
}
public class RegionCode : TwoLetterCode<RegionCode>
{
public RegionCode(string language)
: base(language, v => new CultureInfo(v).TwoLetterISORegionName)
{
}
public static RegionCode TryParse(string language)
{
return TwoLetterCode<RegionCode>.TryParse(language, v => new RegionCode(v));
}
}
This is a rather simple question and to me smells awefully like a homework assignment.
You can obviously see the common bits in the code and I'm pretty sure you can make an attempt at it yourself by putting such things into a super-class.
You could maybe combine them into a Locale class, which stores both Language code and Region code, has accessors for Region and Language plus one parse function which also allows for strings like "en_gb"...
That's how I've seen locales be handled in various frameworks.
These two, as they stand, aren't going to refactor well because of the static methods.
You'd either end up with some kind of factory method on a base class that returns an a type of that base class (which would subsequently need casting) or you'd need some kind of additional helper class.
Given the amount of extra code and subsequent casting to the appropriate type, it's not worth it.
Create a generic base class (eg AbstractCode<T>)
add abstract methods like
protected T GetConstructor(string code);
override in base classes like
protected override RegionCode GetConstructor(string code)
{
return new RegionCode(code);
}
Finally, do the same with string GetIsoName(string code), eg
protected override GetIsoName(string code)
{
return new RegionCode(code).TowLetterISORegionName;
}
That will refactor the both. Chris Kimpton does raise the important question as to whether the effort is worth it.
I'm sure there is a better generics based solution. But still gave it a shot.
EDIT: As the comment says, static methods can't be overridden so one option would be to retain it and use TwoLetterCode objects around and cast them, but, as some other person has already pointed out, that is rather useless.
How about this?
public class TwoLetterCode {
public readonly string Value;
public static TwoLetterCode TryParseSt(string tlc) {
if (tlc == null)
{
return null;
}
if (tlc.Length > 2)
{
tlc = tlc.Substring(0, 2);
}
try
{
return new TwoLetterCode(tlc);
}
catch (ArgumentException)
{
return null;
}
}
}
//Likewise for Region
public class LanguageCode : TwoLetterCode {
public LanguageCode(string language)
{
this.Value = new CultureInfo(language).TwoLetterISOLanguageName;
}
public static LanguageCode TryParse(string language) {
return (LanguageCode)TwoLetterCode.TryParseSt(language);
}
}