How to get Element ID in schedules with c# and revit API? similar to this video with Dynamo - https://youtu.be/U-tVoCYilxo - but with c# and revit api.
When I execute my code, the third column doesn't appear and I get only two columns with width and height.
(I don't know what to write more - StackOverflow doesn't let me to post my issue without writing more text...)
here is my try:
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Nice3point.Revit.Toolkit.External;
using Ecoworx.Core.Elements;
namespace Ecoworx
{
[Transaction(TransactionMode.Manual)]
public class CreateScheduleCommandHandler : ExternalEventHandler
{
public override void Execute(UIApplication uiapp)
{
UIDocument uidoc = uiapp.ActiveUIDocument;
Application app = uiapp.Application;
Document doc = uidoc.Document;
CreateSchedule(uiapp);
}
public static void CreateSchedule(UIApplication uiapp)
{
UIDocument uidoc = uiapp.ActiveUIDocument;
Application app = uiapp.Application;
Document doc = uidoc.Document;
using (Transaction t = new Transaction(doc, "Create single-category"))
{
t.Start();
// Create schedule
ViewSchedule vs = ViewSchedule.CreateSchedule(doc, new ElementId(BuiltInCategory.OST_Windows));
ElementId someId = new ElementId(BuiltInCategory.OST_Windows);
BuiltInParameter bip = (BuiltInParameter)(someId.IntegerValue);
doc.Regenerate();
// Add fields to the schedule
AddRegularFieldToSchedule(vs, new ElementId(BuiltInParameter.CASEWORK_WIDTH));
AddRegularFieldToSchedule(vs, new ElementId(BuiltInParameter.CASEWORK_HEIGHT));
AddRegularFieldToSchedule(vs, new ElementId(bip));
t.Commit();
}
}
public static void AddRegularFieldToSchedule(ViewSchedule schedule, ElementId paramId)
{
ScheduleDefinition definition = schedule.Definition;
// Find a matching SchedulableField
SchedulableField schedulableField =
definition.GetSchedulableFields().FirstOrDefault(sf => sf.ParameterId == paramId);
if (schedulableField != null)
{
// Add the found field
definition.AddField(schedulableField);
}
}
}
}
It seems like you're trying to cast an ElementId to a BuiltInParameter and then back to an ElementId.
Doesn't passing the id directly solve the problem?
So like this:
ElementId someId = new ElementId(BuiltInCategory.OST_Windows);
doc.Regenerate();
// Add fields to the schedule
AddRegularFieldToSchedule(vs, new ElementId(BuiltInParameter.CASEWORK_WIDTH));
AddRegularFieldToSchedule(vs, new ElementId(BuiltInParameter.CASEWORK_HEIGHT));
AddRegularFieldToSchedule(vs, someId);
The issue is in the Element ID of the parameter that will host the Element ID Property.
You have to get the ElementId of the parameter and then pass it into your method that shows the field in the schedule.
Related
I have a question about the function search Handler in xamarin. I am just starting to learn xamarin, and I am trying in my project with search handler in xamarin to refresh my page with new data from the API. Currently, I am already lucky to retrieve the data, but when I do this, it creates a new page so to speak, but this is not what I want. He would kind of reload the page with new data. I have also already tried to delete previous page with "Shell.Current.Navigation.PopAsync();" But with no residual result. Anyone knows how I can achieve what I want? In addition, I would also like to remove that blur you get after the search. Thanks in advance!
using Eindproject.Models;
using Eindproject.Repository;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Eindproject.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Weather : ContentPage
{
private string icao = "EBBR";
public Weather()
{
InitializeComponent();
}
public Weather(string icao)
{
InitializeComponent();
this.icao = icao;
frontend(icao);
}
public async void frontend(string par_icao)
{
// Get weather
Models.WeatherModel weather = await DataRepository.GetWeatherAsync(par_icao);
// Set data to labels
lblLocation.Text = weather.Station.Name;
lblCode.Text = weather.Code;
lblTemp.Text = weather.Temperature.C.ToString();
lblHumidity.Text = weather.Humidity.Percent.ToString();
lblWind.Text = weather.Wind.Degrees.ToString();
lblPressure.Text = weather.Presure.Hpa.ToString();
lblDate.Text = weather.Date.ToString("G");
lblMetar.Text = weather.Metar;
lblCloud.Text = weather.Clouds[0].text;
// Get sunrise and sunset
SunTimes sunrise = await DataRepository.GetSunTimesAsync("EHBK");
// Set data to labels
lblSunrise.Text = sunrise.Sunrise.ToString("G");
lblSunset.Text = sunrise.Sunset.ToString("G");
}
private void ToolbarItem_Clicked(object sender, EventArgs e)
{
}
}
public class CustomSearchHandler : SearchHandler
{
// When user press enter and confirm get the icao code and search for the weather
protected override void OnQueryConfirmed()
{
// Get the icao code
string icao = Query;
// Call wheather object
Weather weather = new Weather();
// Call frontend
weather.frontend(icao);
}
}
}
this is creating a new instance of Weather and calling its frontend method. That won't do anything useful.
Weather weather = new Weather();
weather.frontend(icao);
Instead you need to use the existing instance that is already displayed to the user
there are many ways to do this, but this might be the simplest
// get the current page
var page = App.Current.MainPage;
// cast it to the correct type
var weather = (Weather)page;
// call its frontend method
page.frontend(icao);
I don't know why this test fails. I created a new function, tested it manually and it works fine.
After that, I attempted to create test, but it always fails.
I don't know why.
It just should clear all records from DB older than 1,5 year, but variable historyToDelete always has 0 records. There is whole test:
using Microsoft.EntityFrameworkCore;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TeamsAllocationManager.Contracts.EmployeeWorkingTypeHistory;
using TeamsAllocationManager.Database;
using TeamsAllocationManager.Domain.Models;
using TeamsAllocationManager.Infrastructure.Handlers.EmployeeWorkingHistory;
namespace TeamsAllocationManager.Tests.Handlers.EmployeeWorkingHistory
{
[TestFixture]
public class ClearOldEmployeeWorkingTypeHistoryRecordsHandlerTest
{
private readonly ApplicationDbContext _context;
public ClearOldEmployeeWorkingTypeHistoryRecordsHandlerTest()
{
DbContextOptions<ApplicationDbContext> options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(databaseName: GetType().Name)
.Options;
_context = new ApplicationDbContext(options);
}
[SetUp]
public void SetupBeforeEachTest()
{
_context.ClearDatabase();
var employeeWorkingTypeHistory1 = new EmployeeWorkingTypeHistoryEntity
{
EmployeeId = Guid.Parse("d6951ec1-c865-41bb-8b83-0fcd81745579"),
WorkspaceType = 0,
Created = new DateTime(2000, 01, 01)};
var employeeWorkingTypeHistory2 = new EmployeeWorkingTypeHistoryEntity
{
EmployeeId = Guid.Parse("8a6c4e1c-2c6d-4b70-a507-7bdae5f75429"),
WorkspaceType = 0,
Created = DateTime.Now
};
_context.EmployeeWorkingTypeHistory.Add(employeeWorkingTypeHistory1);
_context.EmployeeWorkingTypeHistory.Add(employeeWorkingTypeHistory2);
_context.SaveChanges();
}
[Test]
public async Task ShouldClearHistory()
{
// given
int numberOfHistoryToClear = 1;
int expectedInDatabase = _context.EmployeeWorkingTypeHistory.Count() - numberOfHistoryToClear;
var command = new ClearOldEmployeeWorkingTypeHistoryRecordsCommand();
var deletionDate = command.TodayDate.AddMonths(-18);
var historyToDelete = await _context.EmployeeWorkingTypeHistory
.Where(ewth => deletionDate > ewth.Created)
.ToListAsync();
var commandHandler = new ClearOldEmployeeWorkingTypeHistoryRecordsHandler(_context);
// when
bool result = await commandHandler.HandleAsync(command);
// then
Assert.IsTrue(result);
Assert.AreEqual(expectedInDatabase, _context.EmployeeWorkingTypeHistory.Count());
//Assert.IsFalse(_context.EmployeeWorkingTypeHistory.Any(ewth => historyToDelete.Contains(ewth.Id)));
}
}
}
If I found out why it fails, I will fix whole test but now I am stuck.
#Update 1
I found a issue. When im creating dbContext in SetupBeforeEachTest, im setting up Created to 2000.01.01. There is everything ok, but when im going out from this to the first test, when i checking up a DB i always have current date, not provided in SetupBeforeEach (2021.12.27)
SaveChanges when creating record updating Created date, so if you want to change Created date to test in future, you need to create new record first, then save changes, update it and save changes again.
Try to call the SetupBeforeEachTest() method in your ShouldClearHistory() method.
I have created a chat bot using microsoft bot framework v4 sdk. I wanted to log bot user and bot messages to cosmos db.
i am able to log only user messages using below blog https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-howto-v4-storage?view=azure-bot-service-4.0&tabs=csharp#using-cosmos-db .
I expect to log both user and bot responses.
Thankfully, this is pretty easy since ItranscriptLogger and TranscriptLoggerMiddleware already exist.
Create your TranscriptStore Class (new Class file)
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Azure;
using Microsoft.Bot.Schema;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace QuickTestBot_CSharp
{
public class CosmosTranscriptStore : ITranscriptLogger
{
private CosmosDbStorage _storage;
public CosmosTranscriptStore(CosmosDbStorageOptions config)
{
_storage = new CosmosDbStorage(config);
}
public async Task LogActivityAsync(IActivity activity)
{
// activity only contains Text if this is a message
var isMessage = activity.AsMessageActivity() != null ? true : false;
if (isMessage)
{
// Customize this to save whatever data you want
var data = new
{
From = activity.From,
To = activity.Recipient,
Text = activity.AsMessageActivity().Text,
};
var document = new Dictionary<string, object>();
// activity.Id is being used as the Cosmos Document Id
document.Add(activity.Id, data);
await _storage.WriteAsync(document, new CancellationToken());
}
}
}
}
Create and Add the Middleware (in Startup.cs)
[...]
var config = new CosmosDbStorageOptions
{
AuthKey = "<YourAuthKey>",
CollectionId = "<whateverYouWant>",
CosmosDBEndpoint = new Uri("https://<YourEndpoint>.documents.azure.com:443"),
DatabaseId = "<whateverYouWant>",
};
var transcriptMiddleware = new TranscriptLoggerMiddleware(new CosmosTranscriptStore(config));
var middleware = options.Middleware;
middleware.Add(transcriptMiddleware);
[...]
Result:
Note:
This is probably the easiest/best way to do it. However, you can also capture outgoing activities under OnTurnAsync() using turnContext.OnSendActivities() and then write the outgoing activity to storage, as well.
Following this link How to obtain a list of workspaces using Rally REST .NET
I tried the example however when I try to query against sub["Workspaces"] I get the error
RuntimeBinderException was unhandled;
The best overloaded method match for 'Rally.RestApi.RallyRestApi.Query(Rally.RestApi.Request)' has some invalid arguments
I cannot find any other ways to gather a list of workspaces from the subscription using the RallyApi dll for .Net which I obtained from the link provided.
Any help will be much appreciated.
Try to modify that code as follows:
Request wRequest = new Request(sub["Workspaces"]);
QueryResult queryResult = restApi.Query(wRequest);
Here is an entire app:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using Rally.RestApi;
using Rally.RestApi.Response;
namespace Rest_v2._0_test
{
class Program
{
static void Main(string[] args)
{
//Initialize the REST API
RallyRestApi restApi;
restApi = new RallyRestApi("user#co.com", "secret", "https://rally1.rallydev.com", "v2.0");
//get the current subscription
DynamicJsonObject sub = restApi.GetSubscription("Workspaces");
Request wRequest = new Request(sub["Workspaces"]);
//query the Workspaces collection
QueryResult queryResult = restApi.Query(wRequest);
foreach (var result in queryResult.Results)
{
var workspaceReference = result["_ref"];
var workspaceName = result["Name"];
Console.WriteLine( workspaceName + " " + workspaceReference);
}
}
}
}
Below is what I use to log into the database using linq and then I use C# expressions to gather the data I want. The next thing I want to do is convert this data into an XML any Ideas?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Data;
namespace VcacManagementTools.BuildProfiles
{
public static class BuildProfileTools
{
public static ICollection<string> GetExistingBuildProfileNames(string repositoryHostname,
string repositoryUsername,
string repositoryPassword)
{
var url = string.Format("https://{0}/repository/data/ManagementModelEntiti.svc", repositoryHostname);
var managementModelClient = new DynamicOps.ManagementModel.ManagementModelEntities(new Uri(url))
{
Credentials = new NetworkCredential(repositoryUsername, repositoryPassword)
};
return managementModelClient
.GlobalProfiles
.Select(gp => gp.ProfileName)
.ToList();
The Output I recieve is a list of values
If I understood you well, you want to take the data (the list contains the data from the database) and put it in XML file. I used variables to show where to put each data.
In case you have an XML:
try
{
doc = XDocument.Load(spath, LoadOptions.SetBaseUri);
foreach(String propertyData in dataList)
{
XElement root = new XElement(ElementName);
root.Add(new XElement("property1", propertyData));
doc.Element(MainElement).Add(root);
}
doc.Save(spath);
}
catch (Exception)
{
}