public partial class и IExternalCommand

Автор Тема: public partial class и IExternalCommand  (Прочитано 16590 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн mikoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 55
  • Карма: 0
public partial class и IExternalCommand
« : 30-03-2016, 03:31:41 »
Доброго дня !
ПРоблема с partial class, если просто :
Код - C# [Выбрать]
  1. public class MaterialProperties : IExternalCommand
то все понятно работает
но вот с :
Код - C# [Выбрать]
  1. public partial class MaterialProperties : IExternalCommand
уже ничего не работает  >:( ревит ругается что данный класс не носит IExternalCommand


Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: public partial class и IExternalCommand
« Ответ #1 : 30-03-2016, 08:41:29 »
ревит ругается
Наверное Visual Studio все же ругается то.
класс не носит IExternalCommand
Что делает?:) Может быть класс не реализует интерфейс?:)

А по делу. Вообще проблем быть не должно. Для теста написал вот такой вот код:
Код - C# [Выбрать]
  1.     interface IDummy
  2.     {
  3.         void DoSomething();
  4.     }
  5.  
  6.     public partial class Dummy : IDummy
  7.     {
  8.         public void DoSomething()
  9.         {
  10.             throw new NotImplementedException();
  11.         }
  12.     }
  13.  
  14.     public partial class Dummy : IDummy
  15.     {
  16.  
  17.     }
Никто не ругается.

Чтобы понять что же у вас там написано не так, напишу немного теории. Конструкция partial class позволяет определять один и тот же класс в различных местах (или файлах). Фактически  класс один, но его методы/свойства объявлены в разных местах. Это может быть полезно, когда одна часть класса генерируется, а вторая дописывается пользователем (WinForms, WPF, ASP.NET и т.п.). Зачем вам понадобилось разделять класс в данном случае - не знаю. Но если класс должен реализовывать интерфейс или наследовать класс, то это может быть указано как в одном (любом) из partial классов, так и в обоих.
Т.е. записи
Код - C# [Выбрать]
  1.     public partial class Dummy : IDummy
  2.     {
  3.         public void DoSomething()
  4.         {
  5.             throw new NotImplementedException();
  6.         }
  7.     }
  8.  
  9.     partial class Dummy
  10.     {
  11.          
  12.     }
и
Код - C# [Выбрать]
  1.     public partial class Dummy
  2.     {
  3.         public void DoSomething()
  4.         {
  5.             throw new NotImplementedException();
  6.         }
  7.     }
  8.  
  9.     partial class Dummy : IDummy
  10.     {
  11.          
  12.     }
, а также та, что я приводил в самом начале являются верными и не вызывают ошибок.

Так что чтобы понять, что у вас не так, нужно:
1) приложить код всех частей partial класса
2) Написать ошибку так как ее пишет Visual Studio (лучше скриншот), а не своими словами.

Оффлайн mikoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 55
  • Карма: 0
Re: public partial class и IExternalCommand
« Ответ #2 : 30-03-2016, 11:16:11 »
Виктор доброго дня !
Именно Revit , я смотрел все примеры в SDK и нигде нету public partial class, сам Microsoft VS отлично собирает и dll и exe , но Ревит выдает ошибку , может я не правильно пишу файл манифеста. Я в манифесте ссылаюсь на public partial class. Ошибку пока не могу показать так как все на домашнем ПК, а код такой :
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk;
  3. using Autodesk.Revit;
  4. using Autodesk.Revit.DB;
  5. using Autodesk.Revit.UI;
  6.  
  7.  
  8. using Revit.SDK.Samples.FindAndReplaceText.CS;
  9.  
  10. namespace MacroCSharpSamples
  11. {
  12.     [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
  13.     [Autodesk.Revit.DB.Macros.AddInIdAttribute("C62ABA8B-D2D1-483C-B19C-10AA82F4A078")]
  14.     public partial class ThisDocument : IExternalCommand
  15.     {
  16.         private void Module_Startup(object sender, EventArgs e)
  17.         {
  18.              
  19.         }
  20.  
  21.         private void Module_Shutdown(object sender, EventArgs e)
  22.         {
  23.  
  24.         }
  25.  
  26.         #region Revit Macros generated code
  27.         private void InternalStartup()
  28.         {
  29.             this.Startup += new System.EventHandler(Module_Startup);
  30.             this.Shutdown += new System.EventHandler(Module_Shutdown);
  31.         }
  32.         #endregion
  33.  
  34.        
  35.         public void FindAndReplaceWinType()
  36.         {
  37.                 using(Transaction trans = new Transaction(this.Document, "FindAndReplaceWinType"))
  38.                 {
  39.                         trans.Start();
  40.                         FindAndReplaceWinType sample = new FindAndReplaceWinType(this);
  41.                         sample.Run();
  42.                         trans.Commit();
  43.                 }
  44.         }
  45.     }
  46. }

и уже сам класс FindAndReplaceWinType находится в другом файле кода вместе с Win формой. Я пробовал и там и тут задать интерфейс IExternalCommand и итог везде один.

Оффлайн mikoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 55
  • Карма: 0
Re: public partial class и IExternalCommand
« Ответ #3 : 30-03-2016, 11:17:48 »
и в манифесте я ссылаюсь на Revit.SDK.Samples.FindAndReplaceText.CS.ThisDocument

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: public partial class и IExternalCommand
« Ответ #4 : 30-03-2016, 11:22:37 »
Я в манифесте ссылаюсь на public partial class
Приложить файл манифеста.
а код такой
Это код из макроса. Ошибка тоже с макросом возникает? Приведенный код вообще не содержит класса реализующего интерфейс IExternalCommand.

Revit видимо ругается, что класс, объявленный в манифесте не реализует интерфейс. Чтобы понять в чем беда, мне нужно видеть все части partial класса.
И все же, зачем вам partial класс то здесь понадобился? До причины проблемы мы конечно доберемся, но есть подозрения что текущий подход не верен.

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: public partial class и IExternalCommand
« Ответ #5 : 30-03-2016, 11:24:12 »
Приведенный код вообще не содержит класса реализующего интерфейс IExternalCommand.
Хм. вроде точно его там не было... или был?

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: public partial class и IExternalCommand
« Ответ #6 : 30-03-2016, 11:28:58 »
и в манифесте я ссылаюсь на Revit.SDK.Samples.FindAndReplaceText.CS.ThisDocument
Тогда все верно. Класс ThisDocument не реализует интерфейс IExternalCommand. Правильно Revit ругается.

В общем я пока не пойму совсем что вы делаете. берете код из макроса, пытаетесь прикрутить файл манифеста к нему. Делаете это неправильно.
Давайте по порядку.
Пишите макрос или надстройку в Visual Studio?

Оффлайн mikoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 55
  • Карма: 0
Re: public partial class и IExternalCommand
« Ответ #7 : 30-03-2016, 11:36:52 »
Приложить файл манифеста.
только вечером смогу но насколько я могу понять основное это указание названия dll и класса , хотя по памяти могу написать если нужно
Хм. вроде точно его там не было... или был?
я скопировал макрос и забыл добавить интрефейс , потом подредактировал , но дома с кодом все ОК
Это код из макроса. Ошибка тоже с макросом возникает? Приведенный код вообще не содержит класса реализующего интерфейс IExternalCommand.
да это макрос , и я тоже понимаю что он его не содержит но если указать его в других частых класса то Revit опять ругается с той же проблемой.
Вот код другой части :
Код - C# [Выбрать]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Windows.Forms;
  5.  
  6. using Autodesk;
  7. using Autodesk.Revit;
  8. using Autodesk.Revit.DB;
  9. using Autodesk.Revit.DB.Structure;
  10.  
  11. using System.Linq;
  12.  
  13. using MacroCSharpSamples;
  14.  
  15. namespace Revit.SDK.Samples.SearchAndReplaceWinType.CS
  16. {
  17.     public class FindAndReplaceWinType
  18.     {
  19.         /// <summary>
  20.         /// automatically replaces all windows of a given (hardcoded) type with another hardcoded type
  21.         /// </summary>
  22.         private Document m_doc = null;
  23.  
  24.         /// <summary>
  25.         /// Automatic print of all of a certain view type, to the default printer .
  26.         /// </summary>
  27.         private FindAndReplaceWinType()
  28.         {
  29.         }
  30.  
  31.         /// <summary>
  32.         /// ctor wit parameter used to call this sample.
  33.         /// </summary>
  34.         /// <param name="doc"></param>
  35.         public FindAndReplaceWinType(ThisDocument hostDoc)
  36.         {
  37.             m_doc = hostDoc.Document;
  38.         }
  39.  
  40.         /// <summary>
  41.         /// run this sample now
  42.         /// </summary>
  43.         public void Run()
  44.         {
  45.             try
  46.             {
  47.                 // filtrate the windows from the element set.
  48.  
  49.                 ElementClassFilter filter1 = new ElementClassFilter(typeof(FamilyInstance));
  50.                 ElementCategoryFilter filter2 = new ElementCategoryFilter(BuiltInCategory.OST_Windows);
  51.                 LogicalAndFilter andFilter = new LogicalAndFilter(filter1, filter2);
  52.                 FilteredElementCollector collector = new FilteredElementCollector(m_doc);
  53.                 ICollection<Element> arrayFamily = collector.WherePasses(andFilter).ToElements();
  54.  
  55.                 // filtrate the Symbol from the element set to modify the window's type.
  56.  
  57.  
  58.                 ElementClassFilter filter3 = new ElementClassFilter(typeof(FamilySymbol));
  59.                 ElementCategoryFilter filter4 = new ElementCategoryFilter(BuiltInCategory.OST_Windows);
  60.                 LogicalAndFilter andFilter1 = new LogicalAndFilter(filter3, filter4);
  61.                 collector = new FilteredElementCollector(m_doc);
  62.                 ICollection<Element> found = collector.WherePasses(andFilter1).ToElements();
  63.                 ElementArray arraySymbol = new ElementArray();
  64.                 foreach (Element ee in found)
  65.                 {
  66.                     if (ee.Name == "36\" x 72\"")
  67.                     {
  68.                         arraySymbol.Insert(ee, 0);
  69.                         break;
  70.                     }
  71.                 }
  72.  
  73.                 MessageBox.Show("Replace 16\" x 24\" to 36\" x 72\".", "FindAndReplaceWinType");
  74.                 // matching and replacing
  75.                 int replacenum = 0;
  76.                 foreach (Element ee in arrayFamily)
  77.                 {
  78.  
  79.                     FamilyInstance windows = ee as FamilyInstance;
  80.                     if (0 == windows.Symbol.Name.CompareTo("16\" x 24\""))
  81.                     {
  82.                         windows.Symbol = arraySymbol.get_Item(0) as FamilySymbol;
  83.                         replacenum++;
  84.                     }
  85.  
  86.                 }
  87.                 // Show the number of windows modified.
  88.                 MessageBox.Show("Revit has completed its search and has made " + replacenum + " modifications.", "FindAndReplaceWinType");
  89.             }
  90.             catch (Exception ee)
  91.             {
  92.                 MessageBox.Show(ee.Message);
  93.             }
  94.            
  95.         }
  96.     }
  97. }

Оффлайн mikoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 55
  • Карма: 0
Re: public partial class и IExternalCommand
« Ответ #8 : 30-03-2016, 11:39:28 »
В общем я пока не пойму совсем что вы делаете. берете код из макроса, пытаетесь прикрутить файл манифеста к нему. Делаете это неправильно.
Давайте по порядку.
Пишите макрос или надстройку в Visual Studio?
скорее беру макрос и теперь хочу сделать приложение , и я понимаю что проще сделать это просто одним классом без partial но я знаю что позже он усложнится во много раз и буду добавлять к partial много различных классов , и возможно от разных людей.

Оффлайн mikoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 55
  • Карма: 0
Re: public partial class и IExternalCommand
« Ответ #9 : 30-03-2016, 11:42:36 »
и даже если написать
public class FindAndReplaceWinType : IExternalCommand
и в манифесте указать Revit.SDK.Samples.SearchAndReplaceWinType.CS.FindAndReplaceWinType
Revit пишет что класс FindAndReplaceWinType не реализует интерфейс  IExternalCommand
Off-Topic: показать
Прошу прощение за хаотичность в знаниях , я только недавно начал изучать C#  ::)

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: public partial class и IExternalCommand
« Ответ #10 : 30-03-2016, 11:47:25 »
Все смешалось..
Код другой части тоже не содержит ничего - ни partial класса ни класса, реализующего интерфейс.

Пока я вижу, что
1) Проблема никак не связана с partial
2) вы либо перемудрили с написанием кода, либо в принципе не понимаете что делаете.

Когда будет код, на котором возникает ошибка, тогда только я смогу подсказать. Файл манифеста мне не нужен пока, так как и без него видно, что Revit правильно ругается.

И нужен ответ на вопрос - то что дома пишете - это в Visual Studio или макрос? Если Visual Studio - непонятно зачем partial. Если макрос - непонятно зачем манифест.


Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: public partial class и IExternalCommand
« Ответ #11 : 30-03-2016, 11:50:15 »
буду добавлять к partial много различных классов
ой.. все сложнее чем казалось:)
я только недавно начал изучать C# 
в таком случае лучше пока забудьте про partial классы. Как новичку они вообще не нужны вам. Хотя мне, например, как и далеко не новичку, они тоже еще ни разу не пригодились:)

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: public partial class и IExternalCommand
« Ответ #12 : 30-03-2016, 11:52:13 »
public class FindAndReplaceWinType : IExternalCommand
Если при этом код самой функции как сообщении №7, то еще на этапе компиляции должно ругаться. Иначе, вы что то недоговариваете.
Класс, реализующий интерфейс, должен обязательно содержать методы/свойства этого интерфейса.

Оффлайн mikoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 55
  • Карма: 0
Re: public partial class и IExternalCommand
« Ответ #13 : 30-03-2016, 11:54:02 »
Хорошо начну с начала , в SDK документации есть примеры макросов , и пересматривая их я увидел интересный подход с partial
МОжете сами открыть посмотреть
в папке SDK:
Revit 2016 SDK\Macro Samples\Revit_Macro_Samples.rvt
там есть макрос FindAndReplaceWinType
Когда все реализуется через Public class все ясно  но когда у нас есть  public partial class то макрос работает, а приложение нет ......

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: public partial class и IExternalCommand
« Ответ #14 : 30-03-2016, 15:51:07 »
макрос работает, а приложение нет .....
Макросу не нужен ни файл манифеста, ни реализация интерфейса IexternalCommand. partial здесь ни причем совсем. Рекомендую просто разобраться с тем, что такое интерфейсы, либо просто пройти по шагам урок "Моя первая программа в Revit"/