Determining If Element is In Dependent View (Revit API) - c#

I'm trying to write a macro for Revit 2020 and 2018 in C#. So far, I have written a program that takes selected elements and filters them if they are within a particular view. However, issues arise when using dependent views because when selecting all elements in a view, it also selects everything in the other dependent views. I don't want this to happen. I'd like to find a way of filtering elements that are only within one particular dependent view.
I've tried having the user select from all available views, but it still treats a dependent view as though it were the larger superview.
The easiest way to solve this would be if there were a way to check membership to a particular view. However, I haven't figured out how to do this. Any suggestions?

Copied from Tray Gates' answer to check if the parameter exist - check if the view is dependent or callout:
You can check to see if a view is a dependent view using GetPrimaryViewId from a view element.
If the result is -1, it is NOT a dependent view.
If it is any other integer, it is a dependent.
Here is an example:
var views = new FilteredElementCollector(doc)
.OfClass(typeof(View));
foreach (View view in views)
{
ElementId parentId = view.GetPrimaryViewId();
if (parentId.IntegerValue == -1 && !view.IsTemplate)
{
// View is NOT a dependent
}
else if (parentId.IntegerValue != -1 && !view.IsTemplate)
{
// View is dependent
}
}
Note that -1 is shorthand for ElementId.InvalidElementId.
Later: I see that you asked the same question in the Revit API forum thread on Determining If Element is in Dependent View, received other answers there, and discovered that your need is in fact different and more complicated...

Related

How do you set the Database details on Sitecore.Context.Item.Database item in Sitecore

I am currently reviewing an existing Sitecore project. One of the items has a controller rendering that outputs a form onto the Layout. In the Action Method, for the controller rendering, there is a line that seems to get the Item's Database Name credentials. I have had a look at the Item's Layout, however I can't find any Database field. I know that Sitecore.Context.Item is meant to get the current Item. However, I am know sure in the code below, how where Sitecore.Context.Item.Database.Name is pointing to. Any explanation would be really appreciated.
public ActionResult Form()
{
Item currentItem = Sitecore.Context.Item;
if (!IsValid(currentItem))
{
return Redirect(Sitecore.Context.Site.VirtualFolder);
}
FormModel model = new FormModel(currentItem);
model.PageModel.Db = Sitecore.Context.Item.Database.Name;
model.PageModel.ItemId = Sitecore.Context.Item.ID.ToString();
return View(model);
}
Sitecore.Context.Item.Database.Name provides the context database in which you are viewing the item. So if you are inside Experience Editor you will get master or if you are on site itself then you will get web.
Sitecore.Context is to provide context information like item, database or language. So for example Sitecore.Context.Item.Language will provide context language in which you are viewing the content on site.
Your "Database" property is not something you will find in a field or anything - it refers to the Sitecore database where the item is located. In a simple setup that will most likely be "master" or "web". The name property of the database will just refer to a string that indicates the database (master - web - ...).
As in Sitecore your item can come from different databases, this property can be used to identify that source. Published items will in a standard setup be in the web database, the master database will contain all items and versions and is used while editing.

Object with items : View-Controller communication

So, I have no clue how to search for an answer to this problem, mainly because there are several aspects to it which I don't know how to solve. So - here it is.
I have an object, let's call it ObjectWithItems which has a List<Item> of Item objects. Both have separate Views and Controllers (which seems logical to me, but I can't be sure).
What I'm trying to achieve is this – go to Create action of ObjectWithItemsController and fill the necessary information specific to it. Then, I click an ActionLink "Add item", which takes me to the Create action of the ItemController. The View is rendered and I enter information for that specific Item.
What I don't know how to do is the following: when I submit the current Item, it should be passed to the former Create view of the ObjectWithItems and added to the List<Item>. Furthermore, it should contain the information inputted before calling the Item Create method and the rendering of the corresponding View.
I know this is a bit blurry description, but that is because I have just started learning ASP MVC and still don't know what's what. Any tested approaches for this?
Using Session["key"] object allow you to store any kind of object, Ex :
List<Table> Rows = db.Table.Where(t => t.id < 100).ToList(); // 100 first rows
Session["TableRows"] = Rows;
And later when you want to retreive them :
List<Table> Rows = (List<Table>)Session["TableRows"] // don't forget to cast it
Your objects will exist in Session as long as you don't reach the ASP timeout
Communication between View-controller is done through HTTP Post of the form.
< form class="form-horizontal" method="post" >
or #using (Html.BeginForm())
More info here with example

Is it possible to "inject" updates into a Knockout ViewModel?

I'm currently looking for a solution to my issue: In our ASP.NET MVC application there are pages that are used for realtime data visualization of industrial devices. When the page gets loaded, a loading icon is shown while I fetch the viewmodel data with the current values for all the datapoints from a database. That works quite well, but it is static, by which I mean that the values don't change on the page after it finished loading. The web application itself uses a TCP listener that receives messages with values from the devices. These messages (which basically consist of a device id, a datapoint id and the value) don't arrive in fixed intervals but event-based, e.g. when a temperature value changes 0.5 K up or down.
On my page I have some graphical widgets like gauges and many other elements that correctly show the values from the initial data that gets loaded on the page load. They are bound to the Knockout viewmodel.
The problem is this: whenever a new value arrives on the server, I want to show it on the page without the need for a reload. I definitely don't want to re-transmit the whole viewmodel with some hundred datapoints on every message that arrives on the server (appr. 1 to 15 per second). In order to achieve that, I implemented the SignalR framework, which really works great. With that mechanism I now receive the new value in the client window (that means, I receive it in Javascript and now have a value object like described below).
What I need now is this: as every viewmodel gets built dynamically, they are all different. The object and properties tree is not the same for two devices, so each of them can have varying levels of subobjects. The only thing that is the same is the structure of the object that actually holds the value for each datapoint: it always consists of the aforementioned device id, the datapoint id and the value.
I need a way to update the double-type value inside the value object within the viewmodel whose device id and datapoint id match the newly arrived value message (that also consists of these two address-like ID's and the value).
I hope I got the idea across. Is there a way to do this? What would be the best practice for such a mechanism? I recently switched to Knockout-MVC (kMVC nuget package), but I'd also go back to "pure" Knockout.js and some additional scripting if that helps.
Thanks for your help and recommendations!
http://nthdegree.azurewebsites.net/mvvm-2/
Here is an article speaking to the Knockout mapping plugin
The general idea is that you should have your view model code which loads your model.
You would bind up your view model which will have a property you load from the server with an ajax call (see bottom of article).
You then just update the model with the result with
ko.mapping.fromJS(newData, mapping, modelToUpdate)
var mapping = {}; //define your mapping (see documentation or blog post)
function ViewModel(){
var self = this;
self.model = ko.mapping.fromJS({}, mapping);
self.hub = $.connection.myHub();
self.hub.client.updateModel = function(data){
ko.mapping.fromJS(data, mapping, self.model);
};
self.hub.start().done(function(){
//you could either make a call or have the "OnConnected" method trigger an 'updateModel'
});
}
ViewModel properties when linked to a DOM element allows editing which is actually updating the data in the KO observable array. Is it possible for you to change the "graphical widget"'s value (assuming that it is using some property to maintain height and width) using the IDs which you said are consistent?
I have not tested; the other option is to use KO foreach loop and update the related value.

Displaying results in View linq to sql mvc 4

I have been reading and reading , and I can't seem to get this to work at all. I am very very new to asp.net MVC - after all the tutorials I read I finally got this much accomplished.
public class EventsController : Controller
{
private EventsDBDataContext db = new EventsDBDataContext();
public ActionResult Index()
{
var a = (from x in db.tblEvents
where x.StartDate >= DateTime.Now
select x).Take(20).ToList();
return View(a);
}
}
This is successfully finding 20 rows (like it is supposed to). Now how do I display these in the view ?? Does it have to be a strongly typed view?? It doesn't seem like it should have to be... I have tried both , I tried typing a whole view, but for now it would be nice to just get one property of tblEvents to show up in the view. This is not working, I have tried many many variations.
#{foreach( var item in Model){
#Html.DisplayFor( item.ID)
}
}
How do I get the results from the controller displayed in the view? Just the ID is good for now - I can go from there.
The problem is that your View doesn't know what type your Model is. Use the #model syntax to define the type of your model.
#model List<YourEventClass>
#foreach( var item in Model )
{
#item.ID<br />
}
See i.e. here for more information
from the root of the web project you should have a directory called Views. Within the views folder create a new folder named Events. In the Events folder create a razor view named Index. put your markup and template code in this file.
You are correct, views do not need to be strongly typed. I find it's a good idea to do so because it provides another compile time check, but it's not required.
when you run the application you will navigate from the root (typically home/index) to Events/Index. there you should see the list of 20 items rendered in the view.
I guess you can not do something like this:
#{foreach( var item in Model){
#Html.DisplayFor(modelItem => item.ID)
}
unless the view knows what Type Model is returned as (still seems weird that .Net can't figure that out on its own. So I fixed the problem and got the ID displayed properly by adding this to the View.
#model IEnumerable<GetEvents.Models.tblEvent>
This works fine for this example - I am returning one table , so the Model type is just the class for the table. But this doesn't seem right - what if I wanted to query and join tables then what would the Model Type be?? Adding this fixed my problem , but if someone has a better answer for this then I will accept that.

Convention over configuration in ASP.NET MVC

I am relatively new to ASP.NET MVC, and am very impressed with the clarity of the platform so far. However, there is one aspect that I find uncomfortable.
At first, I accepted the fact that when I say
return View();
I am calling a helper method that returns an ActionResult, and makes some assumptions about which view to present, route values, etc. But lately I have been writing code that looks more like this:
return View("Index", new { id = myID })
because it is immediately clear to me what's happening by reading that single line of code.
Lately I have been struggling with the fact that I can have an Index.ASPX view open on the tabs, and I can't immediately tell where it comes from because the IDE doesn't highlight the current tab in the Object Explorer. I haven't resorted to changing the names of the files to ControllerNameIndex.ASPX, but I do put a title in the view that is more specific. Still, it doesn't help much.
How do you deal with these kinds of ambiguities?
I think you answered your own question.
There's no hard rule preventing you from calling your views very specific names, such as "ListOfFooBars" or "EditFizzBuzz" or "AddNewGeeblup". The naming convention for the default view engine only specifies that there's a folder corresponding to your model name under views, and there's an ASPX or ASPC file under that folder that corresponds to your view name.

Categories

Resources