C# anonymous object (javascript like) for adhoc usage. No class definition - c#

I wanted to create an anonymous C# object with no class definition. Similar to javascript object. Sample code not working:
var data = new
{
groups = new object[] {
new {
header = "Facebook",
buttons = new object[] {
new {
label = "Create new post"
}
}
}
}
};

The problem was the new object[]. It is just new []. Working code:
var data = new
{
groups = new [] {
new {
header = "Facebook",
buttons = new [] {
new {
label = "Create new post"
}
}
}
}
};

Related

My code-generated ListBox's items isn't showing any content

I have a code-generated window in WPF, (using dotnet core 3.0 preview 6), and when running my application gets the correct data, and the ListBox is populated with the correct number of rows, but none of them contains values
This is a test-project I'm doing to get familiar with code generated WPF as it's needed for an upcoming project we're doing at work; I would have preferred using XAML but my lead says that that will create issues with code-re-usability.
I at first made sure I used am object which is "clean", (my entities are setup for Linq2db, so I ensured that the attributes couldn't be the culprit), then I tested binding, (just got the "Error 40" -error code, but that isn't relevant to the main problem). I have also changed the type of boxes, but It does not help, (DataGrid did work but it's not what I'm looking for in a visual).
public class ChatWindow : IChatWindow
{
private ObservableCollection<MessageDto> _observableMessages;
private readonly IMessagesRepository _messagesRepository;
public ChatWindow(IMessagesRepository messagesRepository)
{
_messagesRepository = messagesRepository;
Task.Run(async () => { await Updater(); }).ConfigureAwait(false);
}
public async Task ShowAsync(User user)
{
var chatLog = new ListBox()
{
Name = "Chatview",
ItemsSource = _observableMessages,
ItemTemplate = new DataTemplate(typeof(MessageDto)),
DataContext = _observableMessages
};
//var myBinding = new Binding("_observableMessages");
//myBinding.Source = _observableMessages;
//chatLog.SetBinding(ListBox.ItemsSourceProperty, myBinding);
var input = new TextBox()
{
Name = "InputField",
Background = new SolidColorBrush(Color.FromRgb(35, 35, 35))
};
var stackPanel = new StackPanel()
{
Children =
{
chatLog,
input
}
};
var window = new Window()
{
Name = "ChatWindow",
Content = stackPanel,
};
window.Show();
}
private async Task Updater()
{
while (true)
{
var messages = await _messagesRepository.GetAllMessages(1);
_observableMessages = new ObservableCollection<MessageDto>(messages.Select(m => new MessageDto()
{
Timestamp = m.Timestamp,
From = m.From,
Message = m.Message
}));
await Task.Delay(TimeSpan.FromSeconds(10));
}
}
}
class MessageDto
{
public DateTime Timestamp { get; set; }
public long From { get; set; }
public string Message { get; set; }
}
Image of the resultant window, (some styling code was removed from the example code to reduce noise)
Based on Flithor's comment, i did this and it worked perfectly:
private DataTemplate GetDataTemplate()
{
var dataTemplate = new DataTemplate(typeof(MessageDto));
FrameworkElementFactory stackPanelFactory = new FrameworkElementFactory(typeof(StackPanel));
stackPanelFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
FrameworkElementFactory timestamp = new FrameworkElementFactory(typeof(Label));
timestamp.SetBinding(Label.ContentProperty, new Binding("Timestamp"));
FrameworkElementFactory from = new FrameworkElementFactory(typeof(Label));
from.SetBinding(Label.ContentProperty, new Binding("From"));
FrameworkElementFactory message = new FrameworkElementFactory(typeof(Label));
message.SetBinding(Label.ContentProperty, new Binding("Message"));
stackPanelFactory.AppendChild(timestamp);
stackPanelFactory.AppendChild(from);
stackPanelFactory.AppendChild(message);
dataTemplate.VisualTree = stackPanelFactory;
return dataTemplate;
}

How to require a property using Json.NET.Schema?

I am trying to create a schema to ensure that outside-supplied JSON is of the following form:
{ Username: "Aaron" }
Right now, I'm creating a Newtonsoft JSchema object in C# by doing:
var sch = new JSchema()
{
Type = JSchemaType.Object,
AllowAdditionalProperties = false,
Properties =
{
{
"Username",
new JSchema() { Type = JSchemaType.String }
}
}
};
This is close, but does not require the presence of the Username property. I've tried the following:
var sch = new JSchema()
{
Type = JSchemaType.Object,
AllowAdditionalProperties = false,
Properties =
{
{
"Username",
new JSchema() { Type = JSchemaType.String }
}
},
Required = new List<string> { "Username" }
};
But I get:
Error CS0200 Property or indexer 'JSchema.Required' cannot be assigned to -- it is read only
And indeed, the documentation notes that the Required property is read-only:
https://www.newtonsoft.com/jsonschema/help/html/P_Newtonsoft_Json_Schema_JSchema_Required.htm
Am I missing something? Why would the Required property be read-only? How can I require the presence of Username?
You can't set Required (is only a get) use instead this:
var sch = new JSchema()
{
Type = JSchemaType.Object,
AllowAdditionalProperties = false,
Properties =
{
{
"Username",
new JSchema() { Type = JSchemaType.String }
}
},
};
sch.Required.Add("Username");
The answer from #PinBack from 2017 is incorrect: you can use C# Collection Initialization syntax with read-only list properties, like so:
var sch = new JSchema()
{
Type = JSchemaType.Object,
AllowAdditionalProperties = false,
Properties =
{
{
"Username",
new JSchema() { Type = JSchemaType.String }
}
},
Required = // <-- here!
{
"Username"
}
};

Solrnet index data post object list

I use solrnet to index data like below :
var solrFacility = new SolrNetFacility("http://mysolr:8983/solr/testcollection");
var container = new WindsorContainer();
container.AddFacility("solr", solrFacility);
var solr = container.Resolve<ISolrOperations<Dictionary<string, object>>>();
solr.Add(new Dictionary<string, object> {
{"id", "http://google.com/link1"},
{"title", "test.pdf"},
{"content", "abcdefghijk"},
{"author", "Ziv Hsu"},
{"editor", "Ziv Hsu"},
});
solr.Commit();
It's work;
but if I have a object list need to index
is not work it'll get 400 code like below:
public class LSchemaField
{
public List<SchemaField> SchemaFieldList = new List<SchemaField>();
}
public class SchemaField
{
public virtual string id { get; set; }
.....
}
LSchemaField SchemaFieldList = new LSchemaField();
SchemaField SchemaFields = new SchemaField();
SchemaFields.id = ....;
SchemaFieldList.SchemaFieldList.Add(SchemaFields);
SchemaField SchemaFields2 = new SchemaField();
SchemaFields2.id =....;
SchemaFieldList.SchemaFieldList.Add(SchemaFields2);
var solrFacility = new SolrNetFacility("http://mysolr:8983/solr/testcollection");
var container = new WindsorContainer();
container.AddFacility("solr", solrFacility);
var solr = ObjectFactory.GetInstance<ISolrOperations<LSchemaField>>();enter code here
solr.Add(SchemaFieldList );
solr.Commit();
Can it add a object list?
In SchemaField class you need to set SchemaField attribute for each property which you want to add in solr.this will map properties to solr fileds.
https://github.com/mausch/SolrNet/blob/master/Documentation/Mapping.md

Why only the medium tile is getting updated?

I am writing a Windows 10 universal app in C# and i want to create a tile with a specific text on it that can change. Therefore I used the sample code form microsoft MSDN (the second one). But this does not work for all tiles, only the medium one shows the text "medium" on in, the others have just the app logo on it. I wonder what else is needed to force the other tiles to update.
This is the code I used to make the tile update:
public static void updateTile(){
TileContent content = new TileContent() {
Visual = new TileVisual() {
TileSmall = new TileBinding() {
Content = new TileBindingContentAdaptive() {
Children = {
new TileText() { Text = "Small" }
}
}
},
TileMedium = new TileBinding() {
Content = new TileBindingContentAdaptive() {
Children = {
new TileText() { Text = "Medium" }
}
}
},
TileWide = new TileBinding() {
Content = new TileBindingContentAdaptive() {
Children = {
new TileText() { Text = "Wide" }
}
}
},
TileLarge = new TileBinding() {
Content = new TileBindingContentAdaptive() {
Children = {
new TileText() { Text = "Large" }
}
}
}
}
};
// And then update the primary tile
TileUpdateManager.CreateTileUpdaterForApplication().Update(new TileNotification(content.GetXml()));
}

Refactoring WPF code behind

I have a method called get Data which executes my SQL and returns some rows of ContactLists containing Aggregated Labels.At the moment this method is in my code behind and would like to move it to a separate Data Access class. I would appreciate your assistance. Thanks!
Is normal, if i understand your code, you do this operation after ContactList initialization:
contactList.Labels = new ObservableCollection<Label>()
{
new Label() {
Name = dr["LABEL_NAME"].ToString(),
Count = Convert.ToInt32(dr["LABEL_COUNT"])
}
};
For each ContactList is always added one item, you will do something like this:
contactList.Labels = new ObservableCollection<Label>();
foreach(var item in <yourLabelDataSource>)
contactList.Labels.Add(new Label(...));
The solution is like this:
Dictionary<int, ContactList> myContactDictionary = new Dictionary<int, ContactList>();
using (DB2DataReader dr = command.ExecuteReader())
{
while (dr.Read())
{
int id = Convert.ToInt32(dr["CONTACT_LIST_ID"]);
if (!myContactDictionary.ContainsKey(id))
{
ContactList contactList = new ContactList();
contactList.ContactListID = id;
contactList.ContactListName = dr["CONTACT_LIST_NAME"].ToString();
contactList.Labels = new ObservableCollection<Label>()
{
new Label()
{
Name = dr["LABEL_NAME"].ToString(),
Count = Convert.ToInt32(dr["LABEL_COUNT"])
}
};
myContactDictionary.Add(id, contactList);
}
else
{
//Add new label because CONTACT_LIST_ID Exists
ContactList contactList = myContactDictionary[id];
contactList.Labels.Add(
new Label()
{
Name = dr["LABEL_NAME"].ToString(),
Count = Convert.ToInt32(dr["LABEL_COUNT"])
}
);
}
}
}
Ben, for your last question you can use this solution:
else
{
//Add new label because CONTACT_LIST_ID Exists
ContactList contactList = myContactDictionary[id];
string name = dr["LABEL_NAME"].ToString();
var label = contactList.Labels.Where(l => l.Name == name).FirstOrDefault();
if( label != null )
label.Count += Convert.ToInt32(dr["LABEL_COUNT"]);
else
{
contactList.Labels.Add(
new Label()
{
Name = dr["LABEL_NAME"].ToString(),
Count = Convert.ToInt32(dr["LABEL_COUNT"])
}
);
}
I hope this code is readable and helpfulL!
}
This is other response:
Create and Object Model that can contain your required data:
public class DataResult
{
public ObservableCollection<AggregatedLabel> AggregatedLabels { get; set; }
public ObservableCollection<ContactList> ContactLists { get; set; }
}
You can build a method that return DataResult object, in your method (GetData()), you can valorize the two different properties (AggregatedLabels and ContactsList) with your DB Result. In the and you can return DataResult Object.
A little example here:
public DataResult GetData()
{
DataResult result = new DataResult();
result.AggregatedLabels = new ObservableCollection<AggregatedLabel>();
result.ContactLists = new ObservableCollection<ContactList>();
// Manipulate data result with your method logic like in this examle:
foreach(var something in dbResult)
{
ContactList cl = new ContactList() {
//Binding from something
}
result.ContactLists.Add(cl);
}
return result; //return your Object Model with required Data!
}
I hope it is conceptually clear

Categories