https://docs.microsoft.com/ko-kr/visualstudio/deployment/walkthrough-downloading-assemblies-on-demand-with-the-clickonce-deployment-api?view=vs-2022 

 

주문형 어셈블리 다운로드(ClickOnce API) - Visual Studio (Windows)

ClickOnce 애플리케이션의 특정 어셈블리를 선택 사항으로 표시하고 공용 언어 런타임에 필요할 때 다운로드하는 방법을 알아봅니다.

docs.microsoft.com

 

 

 

연습: ClickOnce 배포 API를 통해 주문형 어셈블리 다운로드

 

기본적으로 ClickOnce 애플리케이션에 포함된 모든 어셈블리는 애플리케이션을 처음 실행할 때 다운로드됩니다. 그러나 소수의 사용자가 사용하는 일부 애플리케이션이 있을 수 있습니다. 이 경우 해당 형식 중 하나를 만들 때에만 어셈블리를 다운로드하고자 할 수 있습니다. 다음 연습에서는 애플리케이션의 특정 어셈블리를 "선택 사항"으로 표시하는 방법 및 CLR(공용 언어 런타임)에서 요청할 때 System.Deployment.Application 네임스페이스에 있는 클래스를 사용하여 이를 다운로드하는 방법을 설명합니다.

 참고

이 절차를 사용하려면 완전 신뢰 상태에서 애플리케이션을 실행해야 합니다.

사전 요구 사항

이 연습을 완료하려면 다음 구성 요소 중 하나가 필요합니다.

  • Windows SDK. Windows SDK는 Microsoft 다운로드 센터에서 다운로드할 수 있습니다.
  • Visual Studio.

프로젝트 만들기

주문형 어셈블리를 사용하는 프로젝트를 만들려면

  1. ClickOnceOnDemand라는 디렉터리를 만듭니다.
  2. Windows SDK 명령 프롬프트 또는 Visual Studio 명령 프롬프트를 엽니다.
  3. ClickOnceOnDemand 디렉터리로 변경합니다.
  4. 다음 명령을 사용하여 퍼블릭/프라이빗 키 쌍을 생성합니다.
    sn -k TestKey.snk
    
  5. cmd복사
  6. 메모장 또는 다른 텍스트 편집기를 사용하여 Message라는 단일 속성을 사용하여 DynamicClass라는 클래스를 정의합니다.
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Microsoft.Samples.ClickOnceOnDemand
    {
        public class DynamicClass
        {
            public DynamicClass() {}
    
            public string Message
            {
                get
                {
                    return ("Hello, world!");
                }
            }
        }
    }
    
  7. C#복사
  8. 사용하는 언어에 따라 ClickOnceLibrary.cs 또는 ClickOnceLibrary.vb 라는 파일로 텍스트를 ClickOnceOnDemand 디렉터리에 저장합니다.
  9. 파일을 어셈블리로 컴파일합니다.
    csc /target:library /keyfile:TestKey.snk ClickOnceLibrary.cs
    
  10. C#복사
  11. 어셈블리를 위한 퍼블릭 키 토큰을 얻으려면 다음 명령을 사용합니다.
    sn -T ClickOnceLibrary.dll
    
  12. cmd복사
  13. 텍스트 편집기를 사용하여 새 파일을 만들고 다음 코드를 입력합니다. 이 코드는 필요한 경우 ClickOnceLibrary 어셈블리를 다운로드하는 Windows Forms 애플리케이션을 만듭니다.
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Reflection;
    using System.Deployment.Application;
    using Microsoft.Samples.ClickOnceOnDemand;
    
    namespace ClickOnceOnDemand
    {
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Unrestricted=true)]
        public class Form1 : Form
        {
            // Maintain a dictionary mapping DLL names to download file groups. This is trivial for this sample,
            // but will be important in real-world applications where a feature is spread across multiple DLLs,
            // and you want to download all DLLs for that feature in one shot. 
            Dictionary<String, String> DllMapping = new Dictionary<String, String>();
    
            public static void Main()
            {
                Form1 NewForm = new Form1();
                Application.Run(NewForm);
            }
    
            public Form1()
            {
                // Configure form. 
                this.Size = new Size(500, 200);
                Button getAssemblyButton = new Button();
                getAssemblyButton.Size = new Size(130, getAssemblyButton.Size.Height);
                getAssemblyButton.Text = "Test Assembly";
                getAssemblyButton.Location = new Point(50, 50);
                this.Controls.Add(getAssemblyButton);
                getAssemblyButton.Click += new EventHandler(getAssemblyButton_Click);
    
                DllMapping["ClickOnceLibrary"] = "ClickOnceLibrary";
                AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
            }
    
            /*
             * Use ClickOnce APIs to download the assembly on demand.
             */
            private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
            {
                Assembly newAssembly = null;
    
                if (ApplicationDeployment.IsNetworkDeployed)
                {
                    ApplicationDeployment deploy = ApplicationDeployment.CurrentDeployment;
    
                    // Get the DLL name from the Name argument.
                    string[] nameParts = args.Name.Split(',');
                    string dllName = nameParts[0];
                    string downloadGroupName = DllMapping[dllName];
    
                    try
                    {
                        deploy.DownloadFileGroup(downloadGroupName);
                    }
                    catch (DeploymentException de)
                    {
                        MessageBox.Show("Downloading file group failed. Group name: " + downloadGroupName + "; DLL name: " + args.Name);
                        throw (de);
                    }
    
                    // Load the assembly.
                    // Assembly.Load() doesn't work here, as the previous failure to load the assembly
                    // is cached by the CLR. LoadFrom() is not recommended. Use LoadFile() instead.
                    try
                    {
                        newAssembly = Assembly.LoadFile(Application.StartupPath + @"\" + dllName + ".dll," +  
                "Version=1.0.0.0, Culture=en, PublicKeyToken=03689116d3a4ae33");
                    }
                    catch (Exception e)
                    {
                        throw (e);
                    }
                }
                else
                {
                    //Major error - not running under ClickOnce, but missing assembly. Don't know how to recover.
                    throw (new Exception("Cannot load assemblies dynamically - application is not deployed using ClickOnce."));
                }
    
    
                return (newAssembly);
            }
    
            private void getAssemblyButton_Click(object sender, EventArgs e)
            {
                DynamicClass dc = new DynamicClass();
                MessageBox.Show("Message: " + dc.Message);
            }
        }
    }
    
  14. C#복사
  15. 코드에서 LoadFile에 대한 호출을 찾습니다.
  16. PublicKeyToken을 이전에 검색한 값으로 설정합니다.
  17. 파일을 Form1.cs 또는 Form1.vb 로 저장합니다.
  18. 다음 명령을 사용하여 실행 파일로 컴파일합니다.
    csc /target:exe /reference:ClickOnceLibrary.dll Form1.cs
    
  19. C#복사

어셈블리를 선택 사항으로 표시

MageUI.exe를 사용하여 ClickOnce 애플리케이션에서 어셈블리를 선택 사항으로 표시하려면

  1. MageUI.exe 를 사용하여 연습: ClickOnce 애플리케이션 수동으로 배포에 설명된 대로 애플리케이션 매니페스트를 만듭니다. 애플리케이션 매니페스트에 대해 다음 설정을 사용합니다.
    • 애플리케이션 매니페스트의 이름을 ClickOnceOnDemand 로 지정합니다.
    • 파일 페이지의 ClickOnceLibrary.dll 행에서 파일 형식 열을 없음 으로 설정합니다.
    • 파일 페이지의 ClickOnceLibrary.dll 행에서 Group 열에 ClickOnceLibrary.dll을 입력합니다.
  2. MageUI.exe 를 사용하여 연습: ClickOnce 애플리케이션 수동으로 배포에 설명된 대로 배포 매니페스트를 만듭니다. 배포 매니페스트에 대해 다음 설정을 사용합니다.
    • 배포 매니페스트의 이름을 ClickOnceOnDemand로 지정합니다.

새 어셈블리 테스트

요청 시 어셈블리를 테스트하려면

  1. 웹 서버에 ClickOnce 배포를 업로드합니다.
  2. 배포 매니페스트에 URL을 입력하여 웹 브라우저에서 ClickOnce로 배포된 애플리케이션을 시작합니다. ClickOnceClickOnceOnDemand 애플리케이션을 호출하고 adatum.com 루트 디렉터리에 업로드하면 URL은 다음과 같습니다.
    http://www.adatum.com/ClickOnceOnDemand/ClickOnceOnDemand.application
    
  3. 복사
  4. 기본 폼이 나타나면 Button을 누릅니다. 메시지 상자 창에 "Hello, World!"라는 문자열이 표시되어야 합니다.

참조


권장 콘텐츠

  • ClickOnce 애플리케이션 - Visual Studio (Windows)

    게시 마법사를 사용하여 처음으로 ClickOnce 애플리케이션을 게시하는 방법을 알아봅니다. Project 디자이너의 게시 페이지에서 나중에 변경합니다.

  • ClickOnce 앱 수동 배포 - Visual Studio (Windows)

    명령줄 버전 또는 매니페스트 생성 및 편집 도구의 그래픽 버전 중 하나를 사용 하 여 ClickOnce 배포를 만드는 방법에 대해 알아봅니다.

  • 로컬 & 원격 데이터 액세스(ClickOnce 앱) - Visual Studio (Windows)

    로컬 및 원격으로 데이터를 읽고 쓰기 위해 ClickOnce 제공하는 다양한 옵션에 대해 알아봅니다.

  • ClickOnce 및 응용 프로그램 설정 - Visual Studio (Windows)

    응용 프로그램 설정 파일이 ClickOnce 응용 프로그램에서 작동 하는 방법 및 사용자가 다음 버전으로 업그레이드 하는 경우 설정 ClickOnce 마이그레이션하는 방법에 대해 알아봅니다.

  • ClickOnce 업데이트 전략 선택 - Visual Studio (Windows)

    ClickOnce 애플리케이션에서 자동 업데이트를 지원하는 방법과 사용할 수 있는 업데이트 전략을 알아봅니다.

  • ClickOnce 응용 프로그램에 대 한 코드 액세스 보안 - Visual Studio (Windows)

    ClickOnce 응용 프로그램에 대 한 코드 액세스 보안 및 코드 액세스 보안 권한을 구성 하는 방법에 대해 알아봅니다.

  • ClickOnce 애플리케이션 보안 - Visual Studio (Windows)

    ClickOnce 응용 프로그램에 대 한 코드에 대 한 액세스를 제한할 수 있는 .NET Framework의 코드 액세스 보안 제약 조건에 대 한 영향에 대해 알아봅니다.

  • ApplicationDeployment 클래스 (System.Deployment.Application)

    현재 배포를 프로그래밍 방식으로 업데이트하도록 지원하고 요청 시에 파일을 다운로드하도록 처리합니다.Supports updates of the current deployment programmatically, and handles on-demand downloading of files. 이 클래스는 상속될 수 없습니다.This class cannot be inherited.

DevExpress.XtraEditors.Repository.RepositoryItemButtonEdit repbeiTemp1 = new DevExpress.XtraEditors.Repository.RepositoryItemButtonEdit();
DevExpress.XtraEditors.Repository.RepositoryItemButtonEdit repbeiTemp2 = new DevExpress.XtraEditors.Repository.RepositoryItemButtonEdit();

gridView.CustomRowCellEdit += (s, e) =>
{
	if (e.Column.FieldName == "col1")
	{
		if (e.CellValue == null)
		{
			e.RepositoryItem = null;
		}
		else
		{
			e.RepositoryItem = repbeiTemp1;
		}
	}
	else if (e.Column.FieldName == "col2")
	{
		if (e.CellValue == null)
		{
			e.RepositoryItem = null;
		}
		else
		{
			e.RepositoryItem = repbeiTemp2;
		}
	}
}

 

참조

: https://docs.devexpress.com/WindowsForms/DevExpress.XtraGrid.Views.Grid.GridView.CustomRowCellEdit

https://docs.devexpress.com/WindowsForms/DevExpress.XtraGrid.Views.Grid.GridView.CustomRowCellEditForEditing

 

Version CurrentVersion
{
	get
	{
		if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
		{
			System.Deployment.Application.ApplicationDeployment ad = System.Deployment.Application.ApplicationDeployment.CurrentDeployment;
			return ad.CurrentVersion;
		}
		else
		{
        	//string fileName = System.Reflection.Assembly.GetExecutingAssembly().Location;
        	//Assembly.LoadFile(fileName).GetName().Version;
			return Assembly.GetExecutingAssembly().GetName().Version;
		}
	}
}

Version UpdateVersion
{
	get
	{
		if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
		{
			System.Deployment.Application.ApplicationDeployment ad = System.Deployment.Application.ApplicationDeployment.CurrentDeployment;
			return ad.UpdatedVersion;
		}
		return null;
	}
}

 

using Newtonsoft.Json.Linq;
//======
Json Write
//======
void WriteJson(){
	JObject jProp = new JObject
	{
		{ "id", "user" },
		{ "name", "Pillar Park" },
	};
	jProp.Add("email", "userpark@userpark.net");
	jProp.Add("country", "Korea (South)");

	JObject jRoot = new JObject(new JProperty("Root", jAttr));

	File.WriteAllText("test.json", jRoot.ToString());
}


//======
Json Read
//======
void ReadJson()
{
	string str = null;
	using (StreamReader sr = new System.IO.StreamReader("test.json"))
	{
		str = sr.ReadToEnd();
		sr.Close();
	}
    //str = File.ReadAllText("test.json");
    
    JObject jRoot = JObject.Parse(str);
    JToken jToken = jRoot["Root"];
    if (jToken["id"] != null)
    {
    	Console.WriteLine(jToken["id"].ToString());
    }
}

 

/**
// KeyDown : 컨트롤에 포커스가 있을 때 키를 누르면 발생합니다.
//   - https://docs.microsoft.com/ko-kr/dotnet/api/system.windows.forms.control.keydown?view=net-5.0
// KeyPress : 컨트롤에 포커스가 있을 때 문자, 스페이스 또는 백스페이스 키를 누르면 발생합니다.
//   - https://docs.microsoft.com/ko-kr/dotnet/api/system.windows.forms.control.keypress?view=net-5.0
// KeyUp : 컨트롤에 포커스가 있을 때 키를 눌렀다 놓으면 발생합니다.
//   - https://docs.microsoft.com/ko-kr/dotnet/api/system.windows.forms.control.keyup?view=net-5.0
 */

//===========================================================

edtSampleControl.KeyDown += OnKeyDown_Enter; //엔터값 확인 
private void OnKeyDown_Enter(object sender, KeyEventArgs e)
{

	Console.WriteLine($"KeyDown code: {e.KeyCode}, value: {e.KeyValue}, modifiers: {e.Modifiers}" + "\r\n");
    
	if (e.KeyCode == Keys.Enter)
	{
		//엔터입력 처리
		e.Handled = true;
	}
}

//===========================================================

edtSampleControl.KeyPress += OnKeyPress_OnlyNumberic; //숫자, 백스페이스, 삭제만 허용
private void OnKeyPress_OnlyNumberic(object sender, KeyPressEventArgs e)
{
	Console.WriteLine($"KeyPress keychar: {e.KeyChar}" + "\r\n");

	//숫자, 백스페이스, 삭제만 허용
	char keyChar = e.KeyChar;
	if (!(char.IsDigit(keyChar) || e.KeyChar == Convert.ToChar(Keys.Back) || e.KeyChar == Convert.ToChar(Keys.Delete)))    //숫자와 백스페이스, 삭제를 제외한 나머지를 바로 처리
	{
		e.Handled = true;
	}
}

//===========================================================

edtSampleControl.KeyPress += OnKeyPress_EscapeToClear; //Escape(ESC) 입력시 Text지우기
private void OnKeyPress_OnlyNumberic(object sender, KeyPressEventArgs e)
{

	Console.WriteLine($"KeyPress keychar: {e.KeyChar}" + "\r\n");
    
	//Escape(ESC) 입력시 Text지우기
	if (e.KeyChar == Convert.ToChar(Keys.Escape))
	{
		Control cmp = sender as Control;
		if(cmp != null)
		{
			cmp.Text = null;
			e.Handled = true;
		}
	}
}

//===========================================================

edtSampleControl.KeyPress += OnKeyUp_Sample;
private void OnKeyUp_Sample(object sender, KeyEventArgs e)
{
	Console.WriteLine( $"KeyUp code: {e.KeyCode}, value: {e.KeyValue}, modifiers: {e.Modifiers}" + "\r\n");
}

본글은 PHPSCHOOL 오랜만에 들어갔다가 Tip&Tech에 유용해 보이는 정보가 있어 일단 스크랩 목적으로 글을 가져와 봅니다.

자세한 글이나, 댓글들을 보실려면 출처로 들어가 확인해보시길 추천합니다.

 

 

 

출처 : 구글드라이브를 이용한 OCR 기능(PHP) (https://phpschool.com/link/tipntech/82695)

=====================================

 

 

<?php 
// 제가 사용하는 서버의 PHP가 구닥다리 5.2라서 
// https://github.com/alchemy-fr/google-plus-api-client 여기에서 가져왔음
include "libraries/google_api/Google_Client.php";
include "libraries/google_api/contrib/Google_DriveService.php";
 
$client = new Google_Client();
$client->setClientId('XXXXXXXXXX.apps.googleusercontent.com');
$client->setClientSecret('XXXXXXXXXXXX');
$client->setRedirectUri('https://XXXXXXXXX/google_drive/google_drive.php');
     
$scope = array(
    'https://www.googleapis.com/auth/drive',
    'https://www.googleapis.com/auth/drive.readonly.metadata',
    'https://www.googleapis.com/auth/drive.file',
    'https://www.googleapis.com/auth/drive.appdata',
    'https://www.googleapis.com/auth/drive.scripts',
    'https://www.googleapis.com/auth/drive.metadata',
    'https://www.googleapis.com/auth/spreadsheets',
);
 
$client->setScopes($scope);
$client->setAccessType('offline');
 
// auth 토큰 유지 로직 시작 - 토큰 가져오기 방법은 각자 알아서 하세요~
// (https://github.com/googleapis/google-api-php-client 예제가 있음)
$hostname = "XXXXX";
$username = "XXXX";
$userpass = "XXXXXXX";
$dbname = "XXXXX";
$connect = mysqli_connect($hostname, $username, $userpass, $dbname);
 
/**
CREATE TABLE token2 (
  seq INT(11) NOT NULL AUTO_INCREMENT,
  type VARCHAR(255) DEFAULT NULL,
  token TEXT DEFAULT NULL,
  PRIMARY KEY (seq)
)
*/
 
$tokenquery="SELECT * FROM token2 WHERE type='original'";
$tokenresult = mysqli_query($connect,$tokenquery);
$tokenrow=mysqli_fetch_assoc($tokenresult);
 
if($tokenrow) {
  extract($tokenrow);
}
$time_created = json_decode($token)->created;
$t=time();
$timediff=$t-$time_created;
$refreshToken = json_decode($token)->refresh_token;
 
if(($timediff>360)&&($token!=''))
{
  $refreshquery="SELECT * FROM token2 WHERE type='refresh'";
  $refreshresult = mysqli_query($connect,$refreshquery);
  $refreshrow=mysqli_fetch_assoc($refreshresult);
   
  if($refreshrow)
  {
    extract($refreshrow);
    $refresh_created = json_decode($token)->created;
    $refreshtimediff=$t-$refresh_created;
    if($refreshtimediff>3600)
    {
      $client->refreshToken($refreshToken);
      $newtoken=$client->getAccessToken();
      $tokenupdate="UPDATE token2 SET token='$newtoken' WHERE type='refresh'";
      mysqli_query($connect,$tokenupdate);
      $token=$newtoken;
    }
    else
    {
      $client->setAccessToken($token);
    }
  }
  else
  {
    $client->refreshToken($refreshToken);
    $newtoken=$client->getAccessToken();
    $tokenupdate="INSERT INTO token2 (type,token) VALUES ('refresh','$newtoken')";
    mysqli_query($connect,$tokenupdate);
    $token=$newtoken;
  }
}
 
//if token is still good.
if(($timediff<3600)&&($token!=''))
{
  $client->setAccessToken($token); 
}
 
mysqli_close($connect);
// 여기까지 auth 토큰 유지 로직
 
$drive = new Google_DriveService($client);
// 업로드할 파일명
$filename = './PICK.pdf_page_1.jpg';
 
// 업로드할 파일의 상세정보
$title = 'test'; // 파일명
$filedata = file_get_contents($filename);
$size = getimagesize($filename);
$mimeType = $size['mime'];
$imgfile = new Google_DriveFile();
$imgfile->setTitle($title);
$imgfile->setMimeType($mimeType);
 
// 드라이브에 올림
$createdFile = $drive->files->insert($imgfile, array(
    'ocr' => true,
    'ocrLanguage' => 'kr',
    'data' => $filedata,
    'mimeType' => $mimeType,
));
 
$req = new Google_HttpRequest($createdFile->exportLinks['text/plain']);
$val = $client->getIo()->authenticatedRequest($req);
$response = $val->getResponseBody(); 
// Temporary Redirect The document has moved here. 페이지이므로 href만 가져온다
preg_match('/href=(["\'])([^\1]*)\1/i', $response, $m);
 
$req = new Google_HttpRequest($m[2]);
$val = $client->getIo()->authenticatedRequest($req);
// html태그랑 스타일 모두 제거
$response = strip_tags(preg_replace('~\<style(.*)\>(.*)\<\/style\>~', '', $val->getResponseBody()),'<p>');
 
// 처리가 완료된 파일은 삭제. 삭제 안하면 계속 누적되어 보기에 안 좋음
$drive->files->delete($createdFile->id);
 
echo nl2br($response);
?>

※ PHPSCHOOL 및 작성글에 CC정보가 없어 복사는 해왔으나 문제가 될 경우 삭제하겠습니다.

 

void SetMultiSelectMode(GridView view, DevExpress.XtraGrid.Views.Grid.GridMultiSelectMode multiSelectMode = DevExpress.XtraGrid.Views.Grid.GridMultiSelectMode.CheckBoxRowSelect) {
	view.OptionsSelection.MultiSelectMode = multiSelectMode;
}

string GetSelectedRows(GridView view) {
	//출처 : DevExpress - "Demo Center 19.2" / WinForms Demos / Data Grid and Editors / UI CUSTOMIZATION / Cell Selection 
    string ret = "";
    int rowIndex = -1;
    if(view.OptionsSelection.MultiSelectMode != GridMultiSelectMode.CellSelect) {
        foreach(int i in gridView1.GetSelectedRows()) {
            DataRow row = gridView1.GetDataRow(i);
            if(ret != "") ret += "\r\n";
            ret += string.Format("{2}: {0} (#{1})", row["CompanyName"], i, Properties.Resources.CompanyName);
        }
    }
    else {
        foreach(GridCell cell in view.GetSelectedCells()) {
            if(rowIndex != cell.RowHandle) {
                if(ret != "") ret += "\r\n";
                ret += string.Format("{1}: #{0}", cell.RowHandle, Properties.Resources.Row);
            }
            ret += "\r\n    " + view.GetRowCellDisplayText(cell.RowHandle, cell.Column);
            rowIndex = cell.RowHandle;
        }
    }
    return ret;
}

 


Windows 플랫폼에서 alert 객체가 지원되지 않아서 Ionic Popup객체로 대체...


var alert = window.alert;


angular.module('myApp', ['ionic'])

.controller('myCtrl', function ($scope, $state, $timeout,$ionicPopup) {
    alert = function (messageText, titleText) {
        if (!titleText || titleText == "undefined") {
            titleText = "";
        }
        var alertPopup = $ionicPopup.alert({
            title: titleText,
            template: messageText
        });
        alertPopup.then(function (res) { });
    };

});



출처 : 자작(userpark.net)


출처 : https://github.com/driftyco/ionic/issues/2885



window.addEventListener('click', function(event) {
  if (Object.prototype.toString.call(event) == '[object PointerEvent]') {
    event.stopPropagation();
  }
}
, true);


또는


ionic.Platform.isIE = function () {
    return ionic.Platform.ua.toLowerCase().indexOf('trident') > -1;
}

if (ionic.Platform.isIE()) {
    angular.module('ionic')
      .factory('$ionicNgClick', ['$parse', '$timeout', function ($parse, $timeout) {
          return function (scope, element, clickExpr) {
              var clickHandler = angular.isFunction(clickExpr) ? clickExpr : $parse(clickExpr);

              element.on('click', function (event) {
                  scope.$apply(function () {
                      if (scope.clicktimer) return; // Second call
                      clickHandler(scope, { $event: (event) });
                      scope.clicktimer = $timeout(function () { delete scope.clicktimer; }, 1, false);
                  });
              });

              // Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click
              // something else nearby.
              element.onclick = function (event) { };
          };
      }]);
}


'Language > Mobile' 카테고리의 다른 글

[Hybrid/Ionic]Windows Platform에서 alert 객체 대체  (1) 2016.11.04

Visual Studio에서 빌드(Build) 또는 디버그(Debug) 시에 발행하는 경고 오류가 하기와 같은 형식으로 발생할 경우 해결 방법

※ 경고라서 특별히 프로그램 실행하는데 문제는 안되나… 꺼림직해서…

경고    1    포함된 interop 어셈블리 'c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies\EnvDTE.dll'에 대한 참조는 ‘~~~~~~~~~~~~~.dll' 어셈블리가 해당 어셈블리에 대해 만든 간접 참조로 인해 만들어졌습니다. 두 어셈블리 중 하나에서 'Interop 형식 포함' 속성을 변경하십시오.   ~~~~

경고    2    포함된 interop 어셈블리 'c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies\EnvDTE80.dll'에 대한 참조는 ‘~~~~~~~~~~~~~.dll' 어셈블리가 해당 어셈블리에 대해 만든 간접 참조로 인해 만들어졌습니다. 두 어셈블리 중 하나에서 'Interop 형식 포함' 속성을 변경하십시오.    ~~~~~

상기 오류 발생한 경우 프로젝트 참조에서 해당 참조를 선택하여 “Interop 형식 포함(Embed Interop Types)”를 False로 변경한다.

   

출처 : 자작(userpark.net)

무지개참조 : http://documentation.devexpress.com/#WindowsForms/clsDevExpressSkinsSkinManagertopic

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace UserPark
{
    static class Program
    {
        /// <summary>
        /// 해당 응용 프로그램의 주 진입점입니다.
        /// </summary>
        [STAThread]
        static void Main()
        {
            //DevExpress 보너스 스킨 등록(활성화)
            DevExpress.UserSkins.BonusSkins.Register();
            //DevExpress.XtraEditors.XtraForm(SDI Form) 스킨기능 활성화
            DevExpress.Skins.SkinManager.EnableFormSkins();
            //DevExpress.XtraEditors.XtraForm(MDI Form) 스킨기능 활성화
            DevExpress.Skins.SkinManager.EnableMdiFormSkins();
           
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new TfrmMain());
        }
    }
}

Program.cs 파일에 Line 16~21 코드를 추가한다.

※ 반드시는 아니나…. 추천….

자세한 설명은 생략

  • Main 폼에 아래 소스 추가하면 스킨갤러리를 사용할 수 있다.
    • “DevExpress.XtraBars.RibbonGalleryBarItem” or “DevExpress.XtraBars.Ribbon.GalleryControl” 타입으로 “GalleryItemSkins”명으로 생성(추가) 하였을 경우 아래 코드를 소스에 추가하여 준다.
DevExpress.XtraBars.Helpers.SkinHelper.InitSkinGallery(GalleryItemSkins, true);

  • 스킨 종류 선언
    • Program.cs에 아래 소수 추가(“DevExpress Dark Style” 사용시)    ※반드시는 아니나…. 추천….
DevExpress.LookAndFeel.UserLookAndFeel.Default.SetSkinStyle("DevExpress Dark Style");
// or
DevExpress.LookAndFeel.UserLookAndFeel.Default.SkinName = "DevExpress Dark Style";

DevExpress.LookAndFeel.UserLookAndFeel.Default.UseWindowsXPTheme = false;

참조에 COM객체 “Windows Script Host Object Model”(1.0) 추가

 

   1: string fileName = @"Temp.lnk";
   2: string fileExt = Path.GetExtension(fileName);
   3: if (fileExt.Trim().ToLower() == ".lnk")
   4: {
   5:     IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
   6:     IWshRuntimeLibrary.IWshShortcut link = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(fileName);
   7:     fileName = link.TargetPath;
   8: }

출처 : 모름

<?xml version="1.0"?>
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>


혼합 모드 어셈블리는 런타임의 버전 'v2.0.50727'에 대해 빌드되며 추가 구성 정보 없이 '4.0' 런타임에 로드할 수 없습니다.
라는 오류가 발생할 경우
app.config 파일에 다음 설정을 입력한다.
<startup useLegacyV2RuntimeActivationPolicy="true">

참조 : http://social.technet.microsoft.com/Forums/en-US/ieitprocurrentver/thread/1342e167-8016-4a75-99bf-4d11d01d9bb1


Windows 7 64bit 환경 기준으로 레지스터리 값 수정하면 됨.

(첨부 파일은 또한 Windows 7 64bit 기준으로 작성 됨)

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]

"EnableIEHosting"=dword:00000001


EnableIEHosting_Windows7_64bit.reg.zip


DevExpress.XtraGrid.Views.Grid.GridView gv = sender as DevExpress.XtraGrid.Views.Grid.GridView;
if (gv.FocusedColumn.FieldName == "DIV_EXP_NO" && gv.ActiveEditor is GridLookUpEdit)
                        {
                            GridLookUpEdit lue = gv.ActiveEditor as GridLookUpEdit;
                            DataTable dt = lue.Properties.DataSource as DataTable;
                            DataView dv = new DataView(dt);
                            string strItem = gv.GetRowCellValue(gv.FocusedRowHandle, gv.Columns["ITEM_NAME"]).ToString();
                            dv.RowFilter = string.Format("ITEM_NAME='{0}'", strItem);
                            lue.Properties.DataSource = dv;
                        }

+ Recent posts