Привязать данные к экземпляру класса вне контекста данных

ОТВЕТЬТЕ НИЖЕ.

Поэтому я использую C# и WPF для создания внешней команды (надстройки) для Autodesk Revit. У меня что-то вроде этого:

Мой Вид содержит:

PWM = new PrintWindowModel(); // this is my ViewModel           
        InitializeComponent();
        DataContext = PWM;

Мой ViewModel содержит свойства для получения и установки данных. Так что эта часть моей привязки данных работает нормально. Он также содержит это (точка входа для Revit):

public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
{
PrintMgr PrintManager = new PrintMgr(commandData);       
  //...
         return Result.Succeeded;
        }

PrintMgr - это класс, который я получил из Revit SDK. Это очень полезный класс, но для работы ему необходимо передать commandData. Он использует commandData для установки текущего документа и тому подобного. Поскольку ему нужны commandData, я не вижу другого выхода, кроме как создать его здесь.

Теперь в моем Xaml у меня есть поле со списком:

<ComboBox Name="AllPrinters"                     
                  DisplayMemberPath="Name"
                  ItemsSource="{Binding GetInstalledPrinters}"                      
                  SelectedItem="{Binding PrintManager.PrinterName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

Теперь ItemsSource работает нормально. Здесь нет проблем.

Проблема кроется в SelectedItem.. Способ привязки явно не работает. (К вашему сведению: у PrintManager.PrinterName есть свойство get & set.)

Теперь, если моему классу не нужны commandData, я мог бы просто пойти

private PrintMgr _printManager;
Public PrintMgr PrintManager 
{ 
get{return_printManager;}
set { _printManager=value;}
}

Но так как моему классу НУЖНЫ commandData, это не поможет.

Обновлено:

Я добавил:

public string PrinterName 
{
get { return PrintManager.PrinterName; } 
set { PrintManager.PrinterName = value; } 
}

и в моем Xaml:

SelectedItem="{Binding PrinterName} 

Затем я удалил datacontext=this; и добавил PrintWndow.Datacontext=this; в метод команды.

Поместите свойство PrinterName в ViewModel. ViewModel - это буквально модель, используемый Посмотреть, а не бизнес-объект, модель или класс обслуживания. В этом случае PrintManager больше всего похож на услугу. Вы можете делегировать свойство PrinterName виртуальной машины свойству PrintManager.PrinterName, т.е. получить / установить вызов PrintManager

Panagiotis Kanavos 10.08.2018 15:55

Вы можете выполнять привязку только к общедоступным свойствам, поэтому вам нужно будет раскрыть имя принтера из такого свойства.

mm8 10.08.2018 16:00

Спасибо за ответ. Я знаю, что это обычный способ привязки. Но как мне это сделать в таком случае? Я не могу пойти: «Вернуть PrintManager.PrinterName;» вне этого метода ... потому что PrintManager там неизвестен ...

Ayazis 10.08.2018 16:29
1
3
170
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам по-прежнему нужно добавить свойство PrintManager в вашу ViewModel, но я предлагаю вам добавить частный сеттер.

private PrintMgr _printManager;
public PrintMgr PrintManager 
{ 
    get{return_printManager;}
    private set { _printManager=value;}
}

В обработчике команд ViewModel:

public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
{
     PrintManager = new PrintMgr(commandData);

     //...
     return Result.Succeeded;
}

Это будет обновлять ваше свойство каждый раз при выполнении команды.

Но я думаю, что это не ваш окончательный ответ, потому что вам все еще нужно подумать о том, что, если команда будет выполняться несколько раз: вы хотите каждый раз регенерировать PrintManager?

И если команда не будет выполнена до визуализации представления, привязка не будет работать, потому что свойство PrintManager будет иметь значение null.

В таком случае у меня есть для вас другое решение :)

(Извините за разметку, Enter публикует комментарий вместо того, чтобы вставлять новую строку). Большое спасибо за помощь! Этот среди других советов, которые вы мне дали, заставил его работать. Помимо того, что сказано выше ^ я также добавил:. общедоступная строка PrinterName {получить {вернуть PrintManager.PrinterName; } установить {PrintManager.PrinterName = значение; }}. и в моем Xaml:. selectedItem = "{Binding PrinterName}. Затем я удалил datacontext = this; и добавил PrintWndow.Datacontext = this; в метод команды.

Ayazis 13.08.2018 10:34

Другие вопросы по теме