Quantcast
Channel: MSDN Blogs
Viewing all 29128 articles
Browse latest View live

How to register for File Dialog notifications from Shell namespace extension

$
0
0

If you are implementing a shell namespace extension and want to know when a file system item in your shell namespace extension is chosen by the user from Open Dialog, this blog post is for you.

The basic steps on how to do this as follows:

  1. Implement IObjectWithSite in your COM class that is passed to SHCreateShellFolderView inSFV_CREATE::psfvcb.
  2. In your implementation of IObjectWithSite::SetSite, query IUnknown *pUnkSite for SID_SExplorerBrowserFrame service to retrieve IFileOpenDialog interface.
    Note: it will be NULL if your namespace extension is not hosted by Open Dialog as the interface name suggests.
  3. Implement IFileDialogEvents::OnFileOk in a COM class and pass it to IFileDialog::Advise (IFileOpenDialog is derived from IFileDialog)

OnFileOK will be called when a file system item in your shell namespace extension is chosen by the user from Open Dialog.

Here is how this can be implemented:

classCFolderViewCB : publicIShellFolderViewCB,

                        publicIFolderViewSettings,

                        publicIObjectWithSite

{

public:

    CFolderViewCB() : _cRef(1), m_pUnkSite(NULL), m_cookie(0), m_fileOpenDialog(NULL) {}

 

    // IUnknown

    IFACEMETHODIMP QueryInterface(REFIIDriid, void **ppv)

    {

        staticconstQITAB qit[] =

        {

            QITABENT(CFolderViewCB, IShellFolderViewCB),

            QITABENT(CFolderViewCB, IFolderViewSettings),

            QITABENT(CFolderViewCB, IObjectWithSite),

            { 0 },

        };

        return QISearch(this, qit, riid, ppv);

    }

 

    IFACEMETHODIMP SetSite(IUnknown *pUnkSite);

    IFACEMETHODIMP GetSite(REFIID riid, void **ppvSite);

 

private:

    IUnknown *m_pUnkSite;

    DWORD m_cookie;

    IFileOpenDialog *m_fileOpenDialog;

};

 

 

HRESULTCFolderViewCB::SetSite(IUnknown *pUnkSite)

{

    if (m_pUnkSite != NULL)

    {

        m_pUnkSite->Release();

 

        if (m_fileOpenDialog != NULL)

        {

            m_fileOpenDialog->Unadvise(m_cookie);

            m_fileOpenDialog->Release();

            m_fileOpenDialog = NULL;

            m_cookie = 0;

        }

    }

 

    m_pUnkSite = pUnkSite;

 

    if (m_pUnkSite != NULL)

    {

        m_pUnkSite->AddRef();

 

        HRESULT hr = IUnknown_QueryService(m_pUnkSite, SID_SExplorerBrowserFrame, IID_PPV_ARGS(&m_fileOpenDialog));

        if (SUCCEEDED(hr))

        {

            IFileDialogEvents *fileDialogEvents;

            hr = FileDialogEvents_CreateInstance(IID_PPV_ARGS(&fileDialogEvents));

            if (SUCCEEDED(hr))

            {

                hr = m_fileOpenDialog->Advise(fileDialogEvents, &m_cookie);

 

                fileDialogEvents->Release();

            }

 

            if (FAILED(hr))

            {

                m_fileOpenDialog->Release();

                m_fileOpenDialog = NULL;

            }

        }

 

        if (FAILED(hr))

        {

            //OutputDebugString(L"Failed to subscribe for IFileDialogEvents::Advise\n");

        }

        

    }

 

    returnS_OK;

}

 

HRESULTSTDMETHODCALLTYPECFolderViewCB::GetSite(REFIIDriid, void **ppvSite)

{

    HRESULT hr = E_FAIL;

 

    if (m_pUnkSite != NULL)

    {

        hr = m_pUnkSite->QueryInterface(riid, ppvSite);

    }

 

    if (FAILED(hr))

    {

        *ppvSite = NULL;

    }

 

    return hr;

}

 

classFileDialogEvents : publicIFileDialogEvents

{

public:

    FileDialogEvents() : _cRef(1) {}

 

    // IUnknown

    IFACEMETHODIMP QueryInterface(REFIIDriid, void **ppv)

    {

        staticconstQITAB qit[] =

        {

            QITABENT(FileDialogEvents, IFileDialogEvents),

            { 0 },

        };

        return QISearch(this, qit, riid, ppv);

    }

 

    IFACEMETHODIMP_(ULONG) AddRef() { returnInterlockedIncrement(&_cRef); }

    IFACEMETHODIMP_(ULONG) Release()

    {

        long cRef = InterlockedDecrement(&_cRef);

        if (0 == cRef)

        {

            deletethis;

        }

        return cRef;

    }

 

    IFACEMETHODIMP OnFileOk(IFileDialog *pfd)

    {

        PWSTR filePath;

        IShellItem *shellItem;

        if (SUCCEEDED(pfd->GetResult(&shellItem)))

        {

            if (SUCCEEDED(shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath)))

            {

                //OutputDebugString(filePath);

                //OutputDebugString(L"\r\n");

                CoTaskMemFree(filePath);

            }

 

            shellItem->Release();

        }

 

        returnS_OK;

    }

 

    IFACEMETHODIMP OnFolderChanging(IFileDialog * /*pfd*/, IShellItem * /*psiFolder*/)

    {

        returnE_NOTIMPL;

    }

    IFACEMETHODIMP OnFolderChange(IFileDialog * /*pfd*/)

    {

        returnE_NOTIMPL;

    }

    IFACEMETHODIMP OnSelectionChange(IFileDialog * /*pfd*/)

    {

        returnE_NOTIMPL;

    }

    IFACEMETHODIMP OnShareViolation(IFileDialog * /*pfd*/, IShellItem * /*psi*/, FDE_SHAREVIOLATION_RESPONSE * /*pResponse*/)

    {

        returnE_NOTIMPL;

    }

    IFACEMETHODIMP OnTypeChange(IFileDialog * /*pfd*/)

    {

        returnE_NOTIMPL;

    }

    IFACEMETHODIMP OnOverwrite(IFileDialog * /*pfd*/, IShellItem * /*psi*/, FDE_OVERWRITE_RESPONSE * /*pResponse*/)

    {

        returnE_NOTIMPL;

    }

 

private:

    ~FileDialogEvents()

    {

        

    };

 

    long _cRef;

};

 

HRESULT FileDialogEvents_CreateInstance(REFIIDriid, void **ppv)

{

    *ppv = NULL;

 

    HRESULT hr = E_OUTOFMEMORY;

    FileDialogEvents *events = new (std::nothrow) FileDialogEvents();

    if (events)

    {

        hr = events->QueryInterface(riid, ppv);

        events->Release();

    }

    return hr;

}

 

 

Additional references:

IExplorerBrowser interface

https://msdn.microsoft.com/en-us/library/windows/desktop/bb761909(v=vs.85).aspx

 

 

 

 


NEWS extension reminded me to get excited about the latest VSO planning features

$
0
0

News is one of the cool Visual Studio productivity extensions, listed on the widgets page. Download and install it today!

image

Back to the latest and exciting features mentioned above.

@CurrentIteration

The days of editing work item queries at the end of every sprint to update the iteration path to point at the new sprint are finally over.

You can now specify @CurrentIteration, save and never edit the query again!

image 

WARNING: Excel will not be happy with this new token and Visual Studio will support it with VS 2015 and VS 2013 Update 5.

Kanban board reordering and inline editing

Move items (cards) up or down within each column of the board to re-order your backlog and change its priority. You can also edit and even add new items.

image

As a consequence my browser, firing up nine project backlogs by default, now starts at the Kanban board and i seldom visit the backlog view.

Kanban board split columns

(1) CUSTOMIZE COLUMNS includes a new feature (2) “Split columns”, which allows you to (3) split each column into two sub-columns – Doing and Done.

image

This allows the development team to move items to the Doing sub-column when work is in-progress, and to the Done sub-column to signal that the item is ready for the next phase.

For example, testers and reviewers in our team watch the Done column like hawks for new work.

Last but most exciting … DoD

Keeping the definition of done (DoD) in obscure program management work items is gone as well!

The development team can now decorate each column with a definition of done.

(1) CUSTOMIZE COLUMNS includes another new feature, (2) Definition of Done, which allows you to (3) edit the DoD definition.

Once defined, you will notice a (4) small icon in the column header.

image

Example #1 – our DoD definitions on the central Ideas Features Kanban board

image

PS: Click on image for a bigger image with better resolution. The DoD text is not that important for this post … showing its easy accessibility on the board is!

Example #3 – our DoD definitions on the Test Planning Guidance Kanban board

image

Simplicity! Yet productive and powerful features!

Final thoughts ….

I was wondering why it took me so long to click on the News tab to get a reminder of these cool features.

While typing this post, I realized that I am spending more time in the Web client and less in Visual Studio for daily Program Manager (PM) tasks.

A really positive sign that the board is very appealing and productive these days … with more to come Smile

Anyone at the #EvansData event and want to get dinner?

$
0
0
Anyone at the #EvansData event and want to get dinner? ...read more...(read more)

Poll: Where is the best place online to learn a programming language? http://ow....

$
0
0
Poll: Where is the best place online to learn a programming language? http://ow.ly/3xxDVD Where is the best place online to learn a programming language? |... opensource.com Our last poll, in which our readers picked their favorite programming lanaguage ...read more...(read more)

ListView の仮想モードを有効にした状態で、Shiftキーを押下しながらリスト上の要素を選択すると例外が発生する

$
0
0

こんにちは、Visual Studio サポート チームです。

今回は、仮想モード有効時の ListView コントロールで例外が発生する現象について、回避策とあわせてご案内します。

 

現象

.NET Framework の Windows フォーム アプリケーションにおいて、Shift キーを押下しながら ListView コントロールの要素を選択すると、以下の例外が発生することがあります。

発生する例外 : System.ArgumentException
発生元クラス : ListViewVirtualItemsSelectionRangeChangedEventArgs
メッセージ : startIndex 値に endIndex 値より大きい値を指定することはできません。

本例外は、ListView コントロールの複数の要素のうち、最初以外の要素を Shift キーを押下しながら選択した後、最初の要素を Shift キーを押下しながら選択すると発生します。

また、この現象は、次の条件に当てはまる場合に発生します。

  • アプリケーションの実行環境が .NET Framework 4 である
  • ListView コントロールの VirtualMode プロパティが True に設定されている

 

回避策

本現象は、.NET Framework 4 の不具合に起因して発生します。
回避策としては、以下の 2 つがあります。

1. .NET Framework をバージョン アップする

本不具合は、.NET Framework 4.5 では修正されています。
このため、実行環境の .NET Framework を 4.5 以上にバージョン アップすることで、現象を回避することができます。

2. アプリケーションに対処コードを追加する

本現象は、以下のような手順でアプリケーションに変更を追加することでも回避することができます。

1. ListView クラスを継承して、以下のような MyListView クラスを作成します。

コード例
--------------------------------------------

    using System.Runtime.InteropServices;

    public class MyListView : ListView
    {
        private const int WM_USER = 0x400;
        private const int WM_REFLECT = WM_USER + 0x1C00;
        private const int WM_NOTIFY = 0x004E;
        private const int LVN_ODSTATECHANGED = ((0 - 100) - 15);
        private const int LVIS_SELECTED = 0x0002;

        [StructLayout(LayoutKind.Sequential)]
        public struct NMHDR
        {
            public IntPtr hwndFrom;
            public IntPtr idFrom; //This is declared as UINT_PTR in winuser.h
            public int code;
        }

        [StructLayout(LayoutKind.Sequential)]
        public class NMLVODSTATECHANGE
        {
            public NMHDR hdr;
            public int iFrom = 0;
            public int iTo = 0;
            public int uNewState = 0;
            public int uOldState = 0;
        }

        protected override void WndProc(ref Message m)
        {
            if (!MyWndProc(ref m))
            {
                base.WndProc(ref m);
            }
        }

        unsafe bool MyWndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_REFLECT + WM_NOTIFY:
                    NMHDR* nmhdr = (NMHDR*)m.LParam;
                    switch (nmhdr->code)
                    {
                        case LVN_ODSTATECHANGED:
                            if (VirtualMode && m.LParam != IntPtr.Zero)
                            {
                                NMLVODSTATECHANGE odStateChange = (NMLVODSTATECHANGE)m.GetLParam(typeof(NMLVODSTATECHANGE));
                                bool selectedChanged = (odStateChange.uNewState & LVIS_SELECTED) != (odStateChange.uOldState & LVIS_SELECTED);
                                if (selectedChanged)
                                {
                                    ListViewVirtualItemsSelectionRangeChangedEventArgs lvvisrce = new ListViewVirtualItemsSelectionRangeChangedEventArgs(odStateChange.iFrom, odStateChange.iTo, (odStateChange.uNewState & LVIS_SELECTED) != 0);
                                    OnVirtualItemsSelectionRangeChanged(lvvisrce);
                                }
                                return true;
                            }
                            break;
                        default:
                            break;
                    }
                    break;
                default:
                    break;
            }
            return false;
        }
    }

--------------------------------------------

2. フォームのデザイナ コード (xxxx.Designer.cs) で、MyListView クラスを使用するよう、以下のように変更します。

コード例
--------------------------------------------

変更前 :

    private System.Windows.Forms.ListView listView1;
    this.listView1 = new System.Windows.Forms.ListView();

変更後 :

    private MyListView listView1;
    this.listView1 = new MyListView();

--------------------------------------------

3. プロジェクトのプロパティから、ビルド - 全般 の [アンセーフ コードの許可] にチェックを入れ、アプリケーションをリビルドします。

 

関連情報

ListView.VirtualMode プロパティ
https://msdn.microsoft.com/ja-jp/library/system.windows.forms.listview.virtualmode(v=vs.100).aspx

 

最後に

マイクロソフトではこの問題を製品の不具合と認識しておりますが、現状では、修正プログラムは提供されておりません。
本問題が発生する環境でアプリケーションを実行する必要がある場合は、お手数ですが、上述の回避策の利用をご検討ください。
弊社製品の不具合でご迷惑をおかけいたしておりますこと、深くお詫び申し上げます。

Understanding the financial implications of cloud on your business

$
0
0

We constantly hear about the momentum of cloud growth in Australia and the opportunity it represents for Microsoft Partners to grow their profitability. But how do the numbers actually stack up? What does cloud mean for your P&L and what are some of the best practices for managing your P&L as you plan and build up your online services offerings including building recurring revenue streams and productising unique IP?

Hui Cheng Tan, Financial Controller at Microsoft Australia, has worked with a number of Microsoft Partners to help them understand the financial impact of growing their cloud offerings. We have teamed up with Hui Cheng to deliver a half day workshop for Microsoft Partners during which she will walk through some key financial modelling tools that you can tailor to your own organisation and adjust, depending on changing circumstances and your own services offerings, to give you a view of the impact on your business during the first years of offering online services. You can take this back to your business to drive further depth discussions on your strategy and business plan for growing your cloud business.

  • Thursday 30th April – Melbourne (half day (morning) session)
  • Friday 1st May – Sydney (half day (afternoon) session)

To register for the workshops you will need your Microsoft Partner Network login.  If you’re not yet an MPN member take a look at Jack Pilon’s blog post on MPN 101 which highlights the benefits and how to sign up.  If you have any further questions or need assistance registering for the workshops please email partnerau@microsoft.com.

Small Basic Guru Awards - Feburary, 2015

$
0
0

Nonki defeated me! =^)

 

 

Guru Award Small Basic Technical Guru - February 2015  

Gold Award Winner

 

Nonki TakahashiSmall Basic: Key InputMichiel Van Hoorn: "Great improvement."
RZ: "Very nice explanation and examples of key input handling"

Silver Award Winner

 

Ed Price - MSFTSmall Basic: The History of the Logo TurtleRZ: "Turtle (Logo) was the first programming language for many, including perhaps some of the Small Basic prorammers. Nice article explaining the history."
Michiel Van Hoorn: "A nice background article and hopefull inspiration for those who want to start in robotics"

Bronze Award Winner

 

Nonki TakahashiSmall Basic: TechNet Wiki Article ListMichiel Van Hoorn: "This is great! Perfect as a local cache of the articles. "
RZ: "A good example"

Also worth a mention were the other entries this month:

 

Congratulations to Nonki and thank you to our Small Basic judges! They are Microsoft employees who help us work on Small Basic V-Next, so it's super valuable to have them involved!

Join the March Guru Competition:

TechNet Guru Contributions - March 2015

 

More about the TechNet Guru Awards:

  

Thanks to all our past Gurus! Your content is super valuable!

   - Ninja Ed

Unified Service Desk の構成 Part 6 : エージェントアプリケーションにデバッガーのホストされたコントロールを構成

$
0
0

みなさん、こんにちは。今回も前回から引き続き Unified Service Desk の構成チュートリアルをご紹介します。なお、今回紹介する内容は基本的に以下の内容に沿っています。
Walkthrough 6:Configure the Debugger hosted control in your agent application

 

事前準備

前回までの構成にコントロールを追加していきますので、以下の記事を参考にして構成を作成しておいてください。今回のシナリオでは Part 1 と Part 3 の構成は必須です。
Unified Service Desk の構成 Part 1 : シンプルなエージェントデスクトップの構成
Unified Service Desk の構成 Part 2 : エージェントアプリケーション内に外部の Web ページを表示
Unified Service Desk の構成 Part 3 : エージェントアプリケーション内に Microsoft Dynamics CRM レコードを表示
Unified Service Desk の構成 Part 4 : エージェント アプリケーション内のセッションに Microsoft Dynamics CRM レコードを表示
Unified Service Desk の構成 Part 5 : セッション名とセッション概要データの表示

 

今回の内容 

USD はデバッガータイプのホストされたコントロールによって、USD の構成のデバッグ情報が提供されます。これは、エージェントアプリケーションの構築や構成における問題解決に役立ちます。今回のチュートリアルでは、エージェントアプリケーションにデバッガータイプのホストされたコントロールを追加する方法をご説明いたします。なお、今回は実際にデバッガーコントロールを利用したデバッグ方法には触れませんが、今後投稿を予定している Unified Service Desk の拡張編にて、CTI イベントルーティングにおける汎用リスナーアダプターの利用をご紹介する際に実際にデバッガーを利用した活用事例をご紹介したいと思います。また、USD のデバッグ方法の詳細を知りたい方は併せて以下の記事もご参照ください。
Debug issues in Unified Service Desk

 

ステップ1:デバッガータイプのホストされたコントロールを作成

  1. Microsoft Dynamics CRM にサインインします。
  2. ナビゲーションで Microsoft Dynamics CRMをクリックし、設定 を選択します。
  3. 設定> Unified Service Desk> ホストされたコントロールをクリックします。
  4. 新規をクリックします。
  5. 新規ホストされたコントロールページで次の値を指定します。

フィールド

名前

Contoso Debugger

並び替え順序

3

表示名

Contoso デバッガー

USD コンポーネントの種類

デバッガー

表示グループ

MainPanel

 

  1. 上書き保存をクリックします。

 

ステップ2:デバッガーのホストされたコントロールを表示するツールバーとアクションコールを追加

Unified Service Desk の構成 Part 3 で作成した Contoso Main Toolbarにツールバーボタンを追加し、ステップ1で作成したデバッガーのホストされたコントロールを表示するためのアクションコールを追加します。

 

  1. 設定> Unified Service Desk>ツール バーをクリックします。
  2. Contoso main Toolbarのレコードをクリックします。
  3. ボタン領域で右隅の ボタンで追加をクリックします。
  4. 新規ツール バー ボタンページにて、次の値を指定します。

フィールド

名前

Contoso Debugger Button

ボタン テキスト

デバッガー

受注

3

 

  1. アクション領域の右隅のアクションコールを追加する ボタンを押します。
  2. アクション領域の検索ボックスにて ENTER キーを押すか検索アイコンをクリックします。検索結果画面にて、このツールバーボタンのアクションコールを作成するために右下隅の新規ボタンを押します。
  3. 新規アクション コールページにて、次の値を指定します。

フィールド

名前

Contoso Action Call: Show Debugger

受注

1

ホストされたコントロール

Contoso Global Manager

アクション

CallDoAction

データ

action=default
application=Contoso Debugger

 

  1. 上書き保存をクリックします。

 

ステップ3:作成したコントロールを構成に追加

このステップでは、構成に割り当てられたユーザーにこのチュートリアルで作成したアクションコールやホストされたコントロールを表示するために、これらのコントロールを構成に追加します。

Unified Service Desk の構成 Part 1で作成した Contoso Configurationに以下を追加します。

コントロール名

コントロールの種類

Contoso Action Call: Show Debugger

アクション コール

Contoso Debugger

ホストされたコントロール

 

  1. 設定> Unified Service Desk> 構成をクリックします。
  2. Contoso Configurationをクリックし、定義情報を開きます。
  3. ナビゲーションにて、Contoso Configurationの隣の下向き矢印をクリックし、アクション コールを選択します。
  4. 既存のアクション コールの追加をクリックし、検索ボックスに Contoso Action Call: Show Debuggerと入力して ENTER を押すか検索アイコンをクリックします。
  5. 作成したアクションコールが検索結果に表示されるので追加します。
  6. 同様に Contoso Configurationの隣の下向き矢印をクリックし、ホストされたコントロールでコントロールを追加します。

 

ステップ4:アプリケーションのテスト

  1. USD クライアントを起動し、Contoso Configurationに割り当てたユーザー資格情報でサインインします。
  2. エージェントアプリケーションのツールバー領域に デバッガーボタンが表示されます。このボタンをクリックするとデバッガーコントロールが表示されます。

 

 

結論

このチュートリアルでは、エージェントアプリケーションにデバッガーコントロールを構成する方法をご紹介しました。本番リリース後の運用フェーズでエージェントにデバッガーボタンを見せたくない場合は、デバッガータイプのホストされたコントロールをエージェント向けの構成から外しておくことで、普段はユーザーに見せないでおくことができます。
次回は、エージェントスクリプトの構成方法をご紹介します。お楽しみに!

 - 小澤 英紀


Let your customers know what's going on by leveraging the XAML LiveSetting property

$
0
0

Your customers who are blind or have low vision use screen readers like Narrator to inform them of what's going on in your app. Narrator will always describe something about the UI that's highlighted with its blue rectangular cursor, as that UI is probably of most interest to your customer at any given moment. For example, when keyboard focus moves to a button and the Narrator cursor is moved along with it, your customer hears the accessible name of the button, followed by "Button". Or if your customer's moved the Narrator cursor to a progress bar that has specific progress percentage values available on it, then as the progress changes, Narrator will announce the new progress values.

However, often your customer will not be informed of UI changes which occur at some point on the screen which is distant from where the Narrator cursor currently is. This is intentional, as to announce such things could often be a big distraction. But this also means that your customer may not be informed of some information that's actually very important to them. For example, say your customer invokes a button and in response a progress bar appears while some operation is performed. If they hear nothing when the progress bar appears, they may wonder if they actually invoked the button or not. And if the operation later completes with an error, and some TextBlock is updated to show a related error string, if your customer hears nothing at that time, they may sit waiting for the operation to succeed and return some useful result to them.

XAML app devs can help their customers by following the two steps described below.

 

Step 1:

You know when your UI is being updated to present important visuals which customers who are blind should be made aware of. So get all such cases listed in your feature spec, in a section specific to the screen reader user experience. For example, notify your customer when progress bars or error-related text strings appear.

 

Step 2:

In order for your customer to be informed of a change in your UI when the Narrator cursor is not explicitly pointing at the UI, you need to do two things:

1. Set the AutomationProperties.LiveSetting property on the element of interest. This makes the UI a "Live region". (The term "Live region" originates from web UI terminology, but "LiveSetting" and "Live region" are used pretty much interchangeably these days when discussing XAML.) When you're setting the AutomationProperties.LiveSetting property on an element, you'll set this to either "Assertive" or "Polite". The value you choose is your recommendation to a screen reader on how urgently you'd like the screen reader to inform your customer of a change to the UI. "Assertive" means you'd like your customer to be notified immediately, (interrupting the screen reader's current in-progress speech if there is any,) and "Polite" means you'd like whatever in-progress speech there happens to be, to be completed before informing your customer of the change to your UI.

The following is a very basic example with a (not localized) TextBlock.

    <TextBlock x:Name="MyTextBlock" Text="No error" AutomationProperties.LiveSetting="Assertive" />

 

2. When the data changes on your element, you must explicitly raise an event to let the screen reader know that some data associated with the element has changed.

For example, with the TextBlock in the earlier snippet:

    var peer = FrameworkElementAutomationPeer.FromElement(MyTextBlock);
    if (peer != null)
    {
        peer.RaiseAutomationEvent(AutomationEvents.LiveRegionChanged);
    }

 

By raising the event, you’re only telling the screen reader that something's changed on the element of interest. You’re not saying what's changed, and you are not specifying exactly what you want your customer to be told. You are simply saying the element's changed, and the screen reader can go on to take whatever action it feels is appropriate.

To illustrate how important this all this, some time back I worked with a gentleman who was blind and had ALS/MND, and he was working hard to try to learn how to send e-mail. He wasn’t proficient with the e-mail package or screen reader, and so needed all the help he could get from the features he was using. But there were times when important UI was displayed in the e-mail app, and his screen reader said nothing. Despite all his efforts, he never became familiar enough with the e-mail app to send e-mail by himself.

Please do consider how you can use LiveSettings in your XAML app to make your customers aware of important things going on in your UI.

 

Q&A

 

1. By setting the LiveSetting property on the element, will the LiveRegionChanged event ever get raised automatically for me?

No. You must always raise the event yourself when appropriate.

 

2. Does the order of setting the new data on the element and raising the LiveRegionChanged event matter?

Yes. Element data might be sent to the screen reader with the event itself, so you'll want the new data set on the element by the time you raise the event.

 

3. Once I've set the current data on the element and raised the LiveRegionChanged event, can I immediately set the data on the element to some new value?

While some screen readers will request that current data is sent up with the event, others may decide to request current data in response to them receiving the event. So be aware that the data set on the element for a short time after the event gets raised might be what gets ultimately supplied to your customer.

 

4. What if I want to notify the screen reader of some property change unrelated to text, eg enabled state of the UI?

When you raise the LiveRegionChanged event, you're not notifying the screen reader of a change in any particular property, rather you're simply saying that the element's changed and your customer should be informed. It's up to the screen reader to decide what to tell your customer in response. In Narrator's case, your customer will often be told whatever they'd hear when explicitly moving Narrator to the element. 

 

5. How does the visibility of the element fit in with this?

The call to FrameworkElementAutomationPeer.FromElement() in the snippet above will return null if the element's not visible. So watch out for the possibility of trying to dereference a null AutomationPeer here. This can get interesting when you've bound the text to be shown visually on the element to some view model property, and also bound the visibility of the element to the same view model property. But in practice, this should still result in the LiveRegionChanged event being raised as required.

 

6. How do I know the LiveRegionChanged is being raised when I run my app?

Run the AccEvent SDK tool and set it up to report all LiveRegionChanged events being raised. The following image shows the AccEvent tool reporting the LiveRegionChanged event being raised by the above code snippet, (once the text on the TextBlock's been set to the new value of "Danger! Danger!".

 

Figure 1: The AccEvent SDK tool reporting a LiveRegionChanged event.  


7. I can see my event in AccEvent, but Narrator's not announcing anything. Why not?

Often when we raise LiveRegionChanged events, we’re also doing other things with our UI around the same time which leads to keyboard focus moving. Narrator will always announce a keyboard focus change to your customer, and that will interrupt whatever Narrator was saying (or about to say) in response to events received prior to the FocusChanged event. So use AccEvent to see if a FocusChanged event was raised soon after the LiveRegionChanged event. If it is, then it’s possible that Narrator’s announcement about the keyboard focus change stomped on the announcement relating to your LiveRegionChanged event.

 

8. Narrator announces something relating to my LiveRegionChanged event way later than I expect. Why?

In response to receiving the LiveRegionChanged event, Narrator may request more information about your UI. If your feature is busy doing some operation in such a way that the thread involved with servicing the request from Narrator (via UI Automation) is unresponsive, then Narrator will be blocked until your thread frees up. As a result, the announcement to your customer gets delayed. So consider if some threads in your feature are blocked shortly after the LiveRegionChanged events are raised.

 

9. Should I raise a LiveRegionChanged event every time a progress bar value changes?

Probably not. Be careful not to flood your customer with data. Certainly let them know that the progress bar's appeared.

Note: Don't forget to give a progress bar a useful name. If your progress bar has no accessible name, then the screen reader won't be able to inform your customer of the purpose of the progress bar. For example, if you show rolling dots progress UI while calculating the number of stars in the sky, give the progress bar a name of (say) "Calculating the number of stars in the sky…".

While you don't want to distract your customer, if you feel progress UI is going to be visible for a long time, you could consider raising a LiveRegionChanged event periodically. But by default, just make sure your customer is aware of the progress UI by announcing it when it appears. Once they know of the existence of the UI, they can move Narrator to it whenever they want to learn the current state of the progress.

 

10. Should a LiveRegionChanged event be raised when the enabled state of a button changes?

By default, no. While announcing a change in the enabled state of a button might seem potentially helpful to your customer, given that all they would hear is the same thing as when they've tabbed to the button, this could be confusing. For example, say they've invoked a radio button and in response a "Download" button elsewhere on the page becomes enabled. If after the radio button is invoked your customer heard something about the radio button, followed by "Download, Button", they may wonder if keyboard focus had automatically moved to the Download button.

 

Lync の更新プログラム(CU) 一覧

$
0
0

こんばんは。 Japan Lync Support Team です。
以前、当ブログにて CU リストが掲載されたページをご紹介いたしましたが、いつのまにか更新されなくなってしまいました...。

1. Lync Server 2013

 ※公開サイトでダウンロード可能なバージョンは最新版のみです。ただしセキュリティパッチ(Sec)の場合、ひとつ前のパッチが公開されている場合もございます。

VersionKBDate
5.0.8308.87131310612015/02/19
5.0.8308.81529373052014/9/23
5.0.8308.80329860722014/9/8
5.0.8308.73829373102014/8/5
5.0.8308.57729050482014/1/8
5.0.8308.55628816842013/10/7
5.0.8308.42028195652013/7/1
5.0.8308.29127815472013/2/27

 

 2. Lync 2013 クライアント

Basic や VDI プラグインも同じバージョンが適用可能です。

VersionKBDate
15.0.4701.10029561742015/03/10
15.0.4693.100029207442015/02/10
15.0.4659.100128899192014/10/29
15.0.4649.100028898602014/9/9
15.0.4623.100028500742014/6/10
15.0.4615.100128809802014/5/13
15.0.4605.100328804742014/4/11
15.0.4569.150828639082014/3/11
15.0.4551.100128176782013/11/12
15.0.4551.100528256302013/11/7
15.0.4517.150428176212013/8/13
15.0.4517.100428174652013/7/9
15.0.4517.100127683542013/6/11
15.0.4481.100427680042013/5/20
15.0.4481.100027605562013/3/20
15.0.4454.150928124612013/2/27

 

3. Lync Server 2010

VersionKBDate
4.0.7577.71030307262015/02/06
4.0.7577.23029570442014/04/24
4.0.7577.22529098882014/01/08
4.0.7577.22328896102013/10/07
4.0.7577.21728607002013/07/12
4.0.7577.21627913812013/03/15
4.0.7577.21127916652013/01/29
4.0.7577.20627724052012/11/06
4.0.7577.20327379152012/10/11
4.0.7577.19927015852012/06/16
4.0.7577.19826983702012/04/20
4.0.7577.19726898462012/03/29
4.0.7577.19026703522012/03/01
4.0.7577.18926704302012/02/07
4.0.7577.18826588182012/01/23
4.0.7577.18326509822011/12/13
4.0.7577.18325149802011/11/19
4.0.7577.17026164332011/09/13
4.0.7577.16725922922011/08/29
4.0.7577.16625715462011/07/25
4.0.7577.13725004422011/04/20

 

4. Lync 2010 クライアント 

VersionKBDate
4.0.7577.445630062092014/11/11
4.0.7577.444629535932014/6/10
4.0.7577.444529535932014/4/17
4.0.7577.441929122082014/1/8
4.0.7577.440928846322013/10/7
4.0.7577.439828426272013/7/12
4.0.7577.439228431602013/7/9
4.0.7577.438828277502013/5/14
4.0.7577.438428153472013/4/9
4.0.7577.437827913822013/3/14
4.0.7577.437427933512013/1/29
4.0.7577.435627371552012/10/11
4.0.7577.410927263822012/10/9
4.0.7577.410327016642012/6/16
4.0.7577.409826932822012/6/12
4.0.7577.409727105842012/5/14
4.0.7577.408726847392012/3/28
4.0.7577.407226703262012/3/1
4.0.7577.406326698962012/2/7
4.0.7577.406126704982012/1/28
4.0.7577.405326474152011/11/21
4.0.7577.405125149822011/11/19
4.0.7577.33626302942011/10/19
4.0.7577.33026249072011/10/11
4.0.7577.31425715432011/7/25
4.0.7577.28025512682011/5/24
4.0.7577.27525409512011/4/27
4.0.7577.25324963252011/4/4
4.0.7577.10824677632010/1/20

 

 

 

Apache Cordova和远程mac代理的Visual Studio工具

$
0
0

[原文发表地址]:Visual Studio Tools for Apache Cordova and the remote mac agent

[原文发表时间]:1/12/2015

峰会上,我们还表明,我们要做更多的事情,使开发人员能够使用Apache Cordova。Cordova是一种可以构建混合手机应用程序的框架,它可以跨越不同现代手机平台:IOS,Android,Windows Phone等。借助于Apache提供的API,在使用HTML,CSS,和JavaScript语言来创建应用程序的同时,我们可以充分利用本地设备的性能。

与Android和windows应用程序略有不同,构建iOS应用程序需要一台Mac运行OS X。同时还需要一个更加无缝的方法,让开发人员构建的iOS直接运行在windows下的Visual Studio上。为了解决这个问题,我们设计了一台Mac上运行的远程代理(vs-mda-remote),为Visual Studio在iOS构建服务。我们已经发布的vs-mda-remote代理,使得从VS上构建到Mac上更加有可能。这是一个最直接的软件,可以运行iOS构建服务和远程调试iOS Cordova应用程序。

vs-mda-remote能够启用工作流,比如一边在Parallels (或者相似的VM解决方案)上运行Visual Studio,一边在Mac OS上构建iOS。使用Parallels和vs-mda-remote构建iOS Apache Cordova工程,在MSDN上有介绍使用vs-mda-remote配置机器的方法。

如果你没有建立一台可用的Mac,可以利用云端的Mac去设置vs-mda-remote。这个解决方法在MSDN上有体现:在云端构建和模拟iOS

想要获得更多的Visual Studio Cordova开发信息,参见Apache Cordova preview 工具。如果遇到任何问题或有疑问,你可以直接联系我们,通过用户之声TwitterStackOverflowemail

-Alex

Alex Moskwa 是Visual Studio的一名项目经理,主要负责Cordova工具。在微软的职业生涯中,他一直专注于构建伟大的Web工具体验。加入微软前,他是一名职业Web开发者。

Visual Studio 2015 CTP 5 可用了

$
0
0

[原文发表地址]:Visual Studio 2015 CTP 5 Available

[原文发表时间]:1/16/2015

今天,我们发布新的产品Visual Studio 2015 CTP 5 在November Preview的基础上增加了一些新的功能,比如,Debugging, Diagnostics,XAML 语言服务和 ASP.NET 5。虽然CTP不是一个主要的版本,但用户可以通过它提供反馈意见,能够促进我们在发布时取得更大的进步。可以在Visual Studio 2015 CTP 5查阅新功能已知问题,也可以下载此版本。另外,为了节约时间,可以使用Azure上的虚拟机。下面是基于November Preview基础上,一些新功能的简单介绍。

Debugging和Diagnostics的改进

当调试的时候会出现新的诊断工具窗口,它能提供调试的事件(使用IntelliTrace),内存使用率和CPU使用率。想要阅读更多关于改进的诊断工具,请点击这里

该窗口将显示在下面的项目类型:

  • 受托管的WPF,WinForm,Console 工程
  • Windows32,Console,MFC工程
  • 使用IIS Express的ASP.NET的工程
  • 本地运行的受托或本地32位Windows Store App工程

(目前该功能不支持ASP.NET 5 和IIS,64位的Windows应用商店,使用JavaScript语言运行在远程设备和手机上的工程)

使用调试器事件的工具(使用IntelliTrace),您可以访问所有的断点,输出和调试会话期间收集的IntelliTrace事件。VS呈现的数据既可以作为一个时间表,也可以作为一个表格视图并且这两个视图是同步的。

当你正在调试程序的时候,内存使用工具可以检测出该应用程序的内存使用情况。也可以比较本地机和托管机的详细快照来分析内存增长和内存泄漏的原因。

当正在调试程序的时候,内存使用工具可以通过查看现场CPU图形来检测你的应用程序内存使用情况。

也可以使用性能和诊断中心的时间表工具(Timeline)来检查和诊断性能问题。该工具通过提供应用程序资源消耗丰富的语义解析和场景中心视图,从而能够帮助提高WPF和Windows Store 8.1 App的性能。你可能会在准备UI框架,网络和磁盘空间请求上花费很多时间,但新工具取代了性能和诊断中心现有的XAML UI响应工具。了解更多关于新的时间表工具(TimeLine),点击这里

新XAML语言服务

我们已经重建了.NET 编译器平台('Roslyn')顶部的XAML语言服务,它提供了丰富的智能感知,更快,更可靠的改进XAML编辑体验。现在,你可能没注意到一个很大的变化,新的架构使得我们增加新的功能更加容易。附加上的功能,比如交叉语言重构操作,提高了过滤和更好的数据绑定智能感知。

由于这种语言服务和基于客户的需求,在Visual Studio 2015中我们更专注于提供给XAML开发人员面向设计的工具。因此,如果要授权Visual Studio 2015以代码为中心的XAML,可以关闭XAML设计功能,Tool->Options-〉Xaml Designer来获得一个代码中心工作区。

增强ASP.NET功能

在这个版本中,我们也在ASP.NET 5上增加了一些新的功能体验,同时也提高了性能。例如,以前的版本添加引用对话框只支持引用其它ASP.NET 5。现在也可以引用标准的C#工程了。我们也做了智能感知和验证改进的HTML,CSS和JavaScript编辑器,以及用于支持客户端任务的运行器,比如,随Runner Explorer运行的Grunt和Gulp。现在就可以收集运行和调试ASP.NET 5工程时的浏览器需求。

我们还改进了项目设置体验。在以前的版本中,运行/调试设置定义在Visual Studio内部,是不能被修改的。在此版本中,您可以重写debugSettings.json文件进行设置。在以后的版本中,将能够访问属性页面来更新这个文件。除了能够运行和调试你的项目,还可以运行和调试从Visual Studio中的project.json文件直接定义的任何命令。阅读更多关于ASP.NET 5 improvements,请点击这里

我们也将TypeScript 1.4作为 Visual Studio 2015 CTP 5发布的一部分,在该版本中,TypeScript可以支持type union,type aliases,和新的ES6功能类型。阅读更多关于TypeScript 1.4发布信息

下载Visual Studio 2015 CTP 5,在下一个版本的Visual Studio和.NET上,通过Via连接或用户之声或者在Visual Studio IDE上发一个笑脸图标来分享您的反馈意见。

非常感谢,

John

John Montgomery, Visual Studio平台项目管理负责人

John在微软工作的15中,一直在做技术开发。在进入Visual Studio核心开发环境之前,一直做的是Windows 8 工具开发的工作。

Troubleshooting "Access Denied" errors

$
0
0

Anyone who has used Windows has encountered the dreaded "Access Denied" error.  (AKA error code 5 or 0x5). This error typically implies you can't do something like open or save a file.  The error implies that you have encountered some type of security issue.

In the past, an "Access Denied" issue came down to 2 things in Windows:

  1. Token
  2. DACL (Discretionary Access Control List)

A token represented a user and Windows compared it to the DACL of the secured object that the user was accessing.  Windows was answering the basic question, "Does the user have the requested access to the secured object?".  Once you dig into these 2 items, explaining an "Access Denied" error is easy but understanding whether this is the expected result is much more difficult.  (I may discuss this further in a future BLOG post).

Lately, solving "Access Denied" issues have become more complex due to a new security feature which was introduced in many years ago (Windows VISTA), Mandatory Integrity Control (Integrity Levels).  The purpose of Integrity Levels was to add an extra security check where a user running untrustworthy code is attempting to do something malicious.  See the following for more information:

https://msdn.microsoft.com/en-us/library/windows/desktop/bb648648(v=vs.85).aspx

There are 4 levels of integrity in Windows.  Different users in Windows have a different default integrity level.

  • Anonymous - Anonymous User
  • Low
  • Medium - Normal User
  • High - Elevated User (Administrator)
  • System - LocalSystem

The best example of Integrity Level Usage is Internet Explorer's Protected Mode (See https://msdn.microsoft.com/en-us/library/bb250462%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 ) Basically, Internet Explorer is running in a Low Integrity Level.  What this means is that even though a user may have the appropriate access to a file, the file cannot be accessed from Internet Explorer.  I mentioned above that an access check was based on the system comparing the user's token with the secured object's DACL.  Well, we need to check one more thing, the integrity level of the user's token and what level can access the secured object.  A user can only access objects that have the same or lower integrity level.  In the case of IE, most files and directories in Windows have a medium or higher integrity level and since IE Is running at a low integrity level, any code running in IE will not be able to access any files or directories even if the user has the appropriate permissions to the file or directory.  The above article goes into details on finding the default low integrity level directory which IE can access.  Integrity levels also impact the registry as well.

The integrity level for the user is stored in the token.  The integrity level for a secured object is actually stored in the SACL but the ACEs are not System Aces but they are called System Mandatory Label ACEs.  The Access Check is still the same but there is an additional check that needs to be made from the token and from the Security Descriptor.

So the next time you are dealing with an "Access Denied" error, do not forget to check the integrity levels of the user and the secured object.  You'll save yourself a lot of time.

Follow us on Twitter, www.twitter.com/WindowsSDK.

 

 

 

Lync 2013 2015年3月の更新がリリースされました。

$
0
0

こんばんは。Lync サポートの久保です。

Lync 2013 (クライアント) の 2015 年 3 月の更新がリリースされております。

 

March 10, 2015 update for Lync 2013 (KB2956174)
http://support.microsoft.com/ja-jp/kb/2956174

 

以下のような問題が修正されます。

March 10, 2015 update for Lync 2013 (KB2956174)
http://support.microsoft.com/ja-jp/kb/2956174

Lync 2013 にオンライン会議でホワイト ボード共有のコンテンツを変更したが表示されません。
http://support.microsoft.com/ja-jp/kb/3040496

2 つ以上のテキストをスクロールできない長い Lync 2013 の [ホワイト ボードのページ
http://support.microsoft.com/ja-jp/kb/3040495

匿名ユーザーは Lync 2013 では、会議では、デスクトップを共有するときに「プレゼンテーションに接続できませんでした」のエラーが発生します。
http://support.microsoft.com/ja-jp/kb/3040494

Lync Online ユーザー検索できない連絡先 Lync 2013 に配置されたプロキシ サーバーがある環境で
http://support.microsoft.com/ja-jp/kb/3040493

Meeting does not start if you click a meeting URL in a meeting invitation email message when Lync 2013 is signing in
http://support.microsoft.com/ja-jp/kb/3040491

Text labels for toll and toll-free numbers disappear from a meeting invitation when you create the meeting in Lync 2013
http://support.microsoft.com/ja-jp/kb/3040489

Outlook 2010 freezes, and then crashes when it runs together with Lync 2013
http://support.microsoft.com/ja-jp/kb/3040488

「Lync ミーティングで問題が見つかりました。Lync 2013 での 15 分を実行して Lync クライアントのままにしてください」のエラーが発生します。
http://support.microsoft.com/ja-jp/kb/3040487

 

新しいバージョンは [ 15.0.4701.1000 ] となります。

引き続き、快適な Lync ライフをお楽しみください。

[Sample Of Mar. 25] How to encode several images to a video in universal Windoows apps

$
0
0
Mar. 25 Sample : https://code.msdn.microsoft.com//How-to-encode-several-to-a-053953d1 This sample demonstrates how to encode several images to an mp4 video using Media Foundation in a C++/CX component. This is a universal Windows app which can be built for both Windows 8.1 and Windows Phone 8.1. You can find more code samples that demonstrate the most typical programming scenarios by using Microsoft All-In-One Code Framework Sample Browser or Sample Browser Visual...(read more)

Nová služba: Azure App Service

$
0
0
Scott Guthrie včera představil novou službu Azure App Service, která kombinuje Azure Websites, Mobile Services a BizTalk Services do jednoho společného prostoru pro hostování aplikací. App Service je integrovaná služba, díky níž je možné vytvářet webové a mobilní aplikace pro jakoukoliv platformu a jednoduše je napojovat na další SaaS aplikace a on-premises systémy. App Service má...(read more)

Small Basic - Make it Easy to Read

$
0
0

Small Basic gives you a lot of freedom to format the different statements in your source code.

For example, you can use white spaces and empty lines to make your code easier to read. You can also add comments anywhere in the program to explain what your code does.

Although your running program doesn’t care about these additions, the way your source code’s laid out in the editor can make it much easier to read.

Of course, if you decide to post your Small Basic programs online, others will see it and try to understand your code, so be sure to use comments and empty lines to make it easier to read! It’ll also help you build great habits as a programmer!

  

Have a Small and Basic week!

   - Ninja Ed & Majed Marji  

Visual Studio Tipps & Tricks, Teil 54: Die Darstellung der Suchergebnisse anpassen

$
0
0

Dieser Tipp hat’s in sich! In diesem Fall dürfen auch die warnenden Worte “Der Tippgeber übernimmt keine Haftung” und “Bitte nur nachmachen, wenn Du auch weißt, was Du tust” nicht fehlen.

Es geht um die Visualisierung der Suchergebnisse im Find Results Fenster in Visual Studio. Die Standarddarstellung nach einem Suchvorgang sieht ungefähr so aus:

image

Wie man unschwer erkennen kann, wird ein großer Teil des Inhalts einer Zeile durch Pfadinformationen eingenommen. Der tatsächliche Code in der Zeile erscheint erst mal etwas weiter rechts. Wenn der Bildschirm zu klein oder die Pfade zu lang sind muss man auch noch scrollen… Das ist für Projekte mit vielen unterschiedlichen Ordnern vielleicht sinnvoll. In vielen Fällen reicht aber tatsächlich auch der Dateiname statt des kompletten Pfades, um genau die gleiche wertvolle Information zu beziehen. Gerade in C# gibt es ja die Konvention, dass Klassennamen auch den Dateinamen entsprechen. Und in der Regel gibt es nicht sehr oft den gleichen Klassennamen innerhalb einer Solution, meistens sogar nur ein einziges mal. Insofern ist die Pfadinformation eigentlich überflüssig und könnte doch auch weggelassen werden, oder?

Um das zu erreichen muss man tief in die Trickkiste greifen: Wir müssen die Registry bemühen – daher auch die eingangs erwähnten warnenden Worte. Wer in der Registry Unsinn treibt kann sich sein System zerstören… bitte seid Euch dessen bewusst!

Den Registryeditor rufen wir über regedit auf. Dort navigieren wir dann zu folgendem Eintrag:

image

Wir finden darunter einen Key “Find result format”. Dieser hat standardmäßig den Wert “$p$e($l,$c):$t \r\n”.

image

Wenn wir das führende $p (für Pfad) durch ein $f (für Dateiname) austauschen, dann bekommen wir die Änderung in Visual Studio sofort zu spüren, sobald wir eine neue Suche starten. Es ist also nicht nötig hierfür Visual Studio neu zu starten.

image

Irgendwie gleich viel übersichtlicher, oder?

 

Kurzer Text am Rande:

Dieser Post ist Teil einer längeren Serie, in der ich ein paar der vielleicht nicht ganz so bekannten Features von Visual Studio vorstellen werde. Ich hoffe, für Euch ist der ein oder andere Kniff dabei, den Ihr noch nicht kanntet. Und wenn ihr ihn doch schon kennt: Seid stolz auf Euch und verratet den Trick auch dem Entwickler neben Euch.

Step up to Windows 10

$
0
0

 

image

In today’s fast paced world we are pulled in many directions. One of the largest tensions we feel is between what we want to do. That could be more time with the family, fun projects at work, or many other activities. The challenge is that we are often so overwhelmed by trying to do what we have to do both in our work as well as personal lives. For many of us today it’s not about work/life balance but rather about figuring out how to live while also working.

In IT we have an additional tension pulling at us. We have to often balance conflicting priorities. On one hand we look to maintain the status quo. Our customers look to us to keep the critical systems up and running at all times. We have to keep company data secure and protect the infrastructure, all while controlling costs. At the same time the business, the marketing and our customers are driving us to stay relevant and stay current. We need to manage change while maintaining stability.

We all get the same 24 hours, and we all have similar tension in our lives. We designed Windows 10 to enable people to take action.

It is now time to step up to Windows 10!

Are you one of the eligible Partners to take a Windows 10 exam (Exam 697) for free—plus get a no-cost retake (Second Shot) on Windows 8 exams if needed?

All of the details are here: https://www.microsoft.com/learning/en-us/windows-upgrade-offer.aspx

This offer is for a limited time only.

Declaring a XAML button programmatically and preventing it from vanishing on mouse over

$
0
0

Sometimes I like to make life difficult for myself, or at least it seems that way. For example, I'm apparently a bit mad, because when writing Windows Store apps I'd sometimes rather declare the various buttons and other UI elements in my C# source code, rather than in XAML. Having an enormous chunk of XAML in my MainPage.xaml file just doesn't make me happy. 

So there I was, writing an app that generates buttons and textboxes on the fly from data stored in a XML file (yeah, don't ask) and it was all working great except than when I declared a button, the default action meant the button would disappear on mouse over. Puff - it vanished. Very unsettling.

Here's what I was doing: first I create a button, give it an image, and remove any outline. Then I add an event. For my app's purposes, I was also giving it a unique ID in its tag field and messing with the positioning a little. Don't worry about that part.

 

Button b = newButton();

var brush = newImageBrush();

brush.ImageSource = newBitmapImage(newUri("ms-appx:///ButtonUp.png"));

b.Height = 32;

b.Width = 32;

b.Background = brush;

b.Margin = newThickness(70, 0, 0, 0);

b.BorderThickness = newThickness(0);

b.Tag = id;

b.Opacity = 0.6;

b.Click += MoveNodeUp_Click;

 

 

Of course my first thought was "Huh?" followed by some experiments to trap the OnMouseOver or OnPointerOver events and stop it from flickering away, but no dice. With a deep sigh I resigned myself to having to mess with XAML control templates (have you seen the default control templates? The one for a button goes on for page after page). Then I discovered I could make one simple addition to my XAML to change the default behavior for all Buttons on the page. And that default behavior would prevent the button from flickering. Hurrah! So in case you might find it useful, here's all you need to add to your MainPage.xaml file:

 

<Page.Resources>

  <Style TargetType="Button">

   <Setter Property="Template">

    <Setter.Value>

     <ControlTemplate TargetType="Button">

      <Border Background="{TemplateBinding Background}">

       <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>

      </Border>

     </ControlTemplate>

    </Setter.Value>

   </Setter>

 

 </Page.Resources>

</Style>

 

 

The great thing is that I didn't need to make a single change to my C# code, and the buttons all worked fine.

Viewing all 29128 articles
Browse latest View live




Latest Images