__property to property - c++-cli

I am converting a project from /oldsyntax to /clr and have problems to convert my properties in the public __gc class Reader which has now become public ref class Reader
I have these properties (amongst others) in the .h file
__property void set_Xml(System::String *value);
__property System::String *get_Xml();
and then in the .cpp file I have
void Reader::set_Xml(System::String *value)
{
if(value->Chars[0] == '<'){
reader->put_xml(stlString(value).c_str());
}
else {
reader->put_xml_file(stlString(value).c_str());
}
}
System::String *Reader::get_Xml()
{
return gcString(reader->get_xml(), reader->state.is_utf8);
}
How do I rewrite this so that it can compile with /clr. I am using Visual Studio 2010 ?

The link posted in the comments has all the information on the new syntax for properties.
Old: Declare methods with a specific naming convention, decorate them with __property.
New: Declare a property block within your class, and have methods with an additional level of scope. (Note: I'm not sure if "additional level of scope" is the proper way to describe it, see below.)
For a property named Xml of type String, the syntax would be:
In the header file:
public ref class Reader
{
public:
property String^ Xml
{
String^ get();
void set(String^ value);
}
}
In the .cpp file:
String^ Reader::Xml::get()
{
return whatever;
}
void Reader::Xml::set(String^ value)
{
whatever = value;
}

Related

Can't reference C++/cx class from xaml? (UWP)

I have a C++ class in my application testclient:
namespace testclient{
namespace models{
ref class myclass sealed{
public:
myclass();
property String^ getstring
{
String^ get()
{
return string;
}
}
private:
String^ string = "test";
}}}
I want to bind a control to the property getstring, and from what little I understand of UWP XAML data binding, I have to include this in the top of the MainPage.xaml: xmlns:data="using:testclient.models Problem is, intellisense is telling me "Undefined namespace. The 'using' URI refers to a namespace called testclient.models that could not be found." What am I doing wrong?
EDIT: I've found the problem goes away when I put the class in Mainpage.Xaml.h, but I'd rather not do this...
Every binding consists of a binding target and a binding source. Typically, the target is a property of a control or other UI element, and the source is a property of a class instance.
If you want to use myclass as datasource to MainPage's UI elements, you need to make sure the instance of the myclass is accessible to MainPage. That's why your first version resulted in error. In order to modify mainPage.Xaml.h as little as possible, you could follow steps below by creating a separate file(I simplified the member of myclass for easy debugging):
1) Create myclass.h:
namespace TestClient{
namespace models{
public ref class myclass sealed
{
private:
int test = 1;
public:
myclass()
{
}
property int gettest
{
int get() { return test; };
}
};
}
}
2) in MainPage.h, add following:
#include "myclass.h"
namespace TestClient
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public ref class MainPage sealed
{
private:
TestClient::models::myclass myTest;
.......
}
.........
}
3) Then you can manipulate myclass data in mainPage.cpp as you want. Codes may be like below:
MainPage::MainPage()
{
InitializeComponent();
int i = this->myTest.gettest;
...........
}
Still I have a question: while so many namespace nested? Also you can find a sample about data binding here just for your reference.

How to use variable from resource another .cs file with "using"

I was wondering how to get a variable equivalent from another .cs file with "using" statement.
Like
using (namespace here)
Output(A, 8);
and the file with (namespace here) would have
A = 3
would I be able to directly refer to the variable, or would I need to locate it some other way?
If you just want to define a bunch of constant values in one location that can be used elsewhere this is the standard pattern you would follow:
namespace MyNameSpace
{
public static class Constants
{
public const int MyFavoriteNumber = 3;
}
}
Then somewhere else you can have:
using MyNameSpace;
namespace MyOtherNameSpace
{
public class MyClass
{
public void Method()
{
Console.WriteLine(Constants.MyFavoriteNumber);
}
}
}
You can't dynamically change the scope of a code like that. What an identifier is, is determined at compile time, so you can't change what it means at runtime.
Make a class or an interface that specifies what it is that you want to use from the different files, then inherit the class or implement the interface to make different implementations in different files. When you use one of the implementations you get the values from that file.
Example:
public interface ICommon {
int A { get; }
}
public class File1 : ICommon {
public int A { get { return 42; } }
}
public class File2 : ICommon {
private int _value = 1;
public int A { get { return _value; } }
}
Now you can use different objects:
ICommon x;
if (something) {
x = new File1();
} else {
x = new File2();
}
Output(x.A, 8);
.CS files contains classes, not variables. If the .CS file contains a class that has a static property A you would just reference that static property:
Output(ClassName.A, 8);
Otherwise you need to provide more context as to what you have and what you're trying to do.

What is the syntax to declare a C++/CX WinRT property with implementation in the .cpp file?

I have a class like this:
public ref class Test
{
public:
property int MyProperty;
};
This works. Now I want to move the implementation of MyProperty to the CPP file. I get compiler errors that the property is already defined when I do this:
int Test::MyProperty::get() { return 0; }
What is the proper syntax for this?
In the header change the declaration to:
public ref class Test
{
public:
property int MyProperty
{
int get();
void set( int );
}
private:
int m_myProperty;
};
Then, in the cpp code file write your definitions like this:
int Test::MyProperty::get()
{
return m_myProperty;
}
void Test::MyProperty::set( int i )
{
m_myProperty = i;
}
The reason you are seeing errors is that you have declared a trivial property where the compiler generates an implementation for you. But, then you tried to provide an implementation explicitly as well. See: http://msdn.microsoft.com/en-us/library/windows/apps/hh755807(v=vs.110).aspx
Most of the examples online only show implementations directly in the class definition.
In the class definition, you need to declare the property as a property with user-declared get and set methods; it cannot be a shorthand property:
public ref class Test
{
public:
property int MyProperty { int get(); void set(int); }
};
Then in the cpp file you may define the get() and set() methods:
int Test::MyProperty::get()
{
return 42;
}
void Test::MyProperty::set(int)
{
// set the value
}

Different access modifiers for property getter/setter in C++/CLI

Is it possible to specify different access modifiers for property getter and setter using C++/CLI syntax? In C# one would write:
class Foo
{
public string Bar
{
get;
internal set;
}
}
This should do:
public:
property String^ Bar
{
String^ get();
private:
void set(String^);
}
(Edited following Hans Passant's comment).

Implementing an interface declared in C# from C++/CLI

Say I have a C# interface called IMyInterface defined as follows:
// C# code
public interface IMyInterface
{
void Foo(string value);
string MyProperty { get; }
}
Assume I also have a C++/CLI class, MyConcreteClass, that implements this interface and whose header is declared as follows:
// C++/CLI header file
ref class MyConcreteClass : IMyInterface
{
public:
};
How does one implement the method Foo and the property MyProperty in the C++/CLI header?
My attempt results in the following compile error:
error C3766: 'MyConcreteClass' must
provide an implementation for the
interface method 'void
IMyInterface::Foo(System::String^
value)'
public ref class MyConcreteClass : public IMyInterface
{
public:
virtual void __clrcall Foo(String^ value) sealed;
virtual property String^ __clrcall MyProperty
{ String^ get() sealed { String::Empty; } }
};
Interfaces need to be defined as virtual. Also note the "public IMy.." after the class decleration, it's a slighly different syntax than C#.
If you can, seal the interface members to improve performance, the compiler will be able to bind these methods more tightly than a typical virtual members.
Hope that helps ;)
I did not compile it but looks good to me... Oh and also, defining your methods as __clrcall eliminates dangers of double thunk performance penalties.
edit
the correct syntax for a property is:
public ref class MyConcreteClass : public IMyInterface
{
public:
virtual property String^ MyProperty
{
String^ get() sealed { return String::Empty; };
void set( String^ s ) sealed { };
}
};
or, when putting the definition in the source file:
public ref class MyConcreteClass : public IMyInterface
{
public:
virtual property String^ MyProperty
{
String^ get() sealed;
void set( String^ s ) sealed;
}
};
String^ MyConcreteClass::MyProperty::get()
{
return String::Empty;
}
void MyConcreteClass::MyProperty::set( String^ )
{
//...
}