すもぎのめも

いろいろあったことをメモしています

バインディングしたプロパティの値をリソースのキーにする

使い方

<TextBlock Text="{sample:ResourceBinding Path=ResourceName}" />

実装

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;

namespace Sample
{
    /// <summary>
    /// リソースキーにバインディングするためのマークアップ。
    /// </summary>
    public class ResourceBinding : MarkupExtension
    {
        /// <summary>
        /// リソースへの参照情報を取得する。
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static object GetResourceReference(DependencyObject obj)
        {
            return obj.GetValue(ResourceReferenceProperty);
        }

        /// <summary>
        /// リソースへの参照情報を設定する。
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        public static void SetResourceReference(DependencyObject obj, object value)
        {
            obj.SetValue(ResourceReferenceProperty, value);
        }

        /// <summary>
        /// ResourceReference 依存関係プロパティ。
        /// </summary>
        public static readonly DependencyProperty ResourceReferenceProperty =
            DependencyProperty.RegisterAttached(
                "ResourceReference",
                typeof(object),
                typeof(ResourceBinding),
                new PropertyMetadata(null));

        /// <summary>
        /// バインディング ソース オブジェクトとして使用するオブジェクトを取得または設定。
        /// </summary>
        public object Source { get; set; }

        /// <summary>
        /// バインディング ソース プロパティへのパスを取得または設定。
        /// </summary>
        public PropertyPath Path { get; set; }

        /// <summary>
        /// 使用する XML バインディング ソースの値を返す XPath クエリを取得または設定。
        /// </summary>
        [DefaultValue(null)]
        public string XPath { get; set; }

        /// <summary>
        /// バインディングのデータ フローの方向を示す値を取得または設定。
        /// </summary>
        [DefaultValue(BindingMode.Default)]
        public BindingMode Mode { get; set; }

        /// <summary>
        /// バインディング ソースを更新するタイミングを決定する値を取得または設定。
        /// </summary>
        [DefaultValue(UpdateSourceTrigger.Default)]
        public UpdateSourceTrigger UpdateSourceTrigger { get; set; }

        /// <summary>
        /// バインディング ターゲットの位置に対して相対的な位置を指定することにより、バインディング ソースを取得または設定。
        /// </summary>
        [DefaultValue(null)]
        public RelativeSource RelativeSource { get; set; }

        /// <summary>
        /// バインディング ソース オブジェクトとして使用する要素の名前を取得または設定。
        /// </summary>
        [DefaultValue(null)]
        public string ElementName { get; set; }

        /// <summary>
        /// <see cref="ResourceBinding"/> クラスの新しいインスタンスを生成。
        /// </summary>
        public ResourceBinding()
        {

        }

        /// <summary>
        /// バインディングするプロパティへのパスを指定して <see cref="ResourceBinding"/> クラスの新しいインスタンスを生成。
        /// </summary>
        /// <param name="path">バインディングするプロパティへのパス。</param>
        public ResourceBinding(string path)
        {
            Path = new PropertyPath(path);
        }


        /// <summary>
        /// マークアップの使用元に値を提供する。
        /// </summary>
        /// <param name="serviceProvider">カスタムサポート用オブジェクト。</param>
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            var provideValueTarget = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
            if (provideValueTarget == null)
            {
                return null;
            }

            // テンプレートがパースされるときは System.Windows.SharedDp が格納されている
            // this を返しておくと再評価時にリソースが反映される
            if (provideValueTarget.TargetObject.GetType().FullName == "System.Windows.SharedDp")
            {
                return this;
            }

            var targetObject = provideValueTarget.TargetObject as FrameworkElement;
            var targetProperty = provideValueTarget.TargetProperty as DependencyProperty;

            if (targetObject == null || targetProperty == null)
            {
                return null;
            }


            // 中継用プロパティにバインディング
            var binding = new Binding
            {
                Path = Path,
                XPath = XPath,
                Mode = Mode,
                UpdateSourceTrigger = UpdateSourceTrigger
            };

            if (RelativeSource != null)
            {
                binding.RelativeSource = RelativeSource;
            }

            if (ElementName != null)
            {
                binding.ElementName = ElementName;
            }

            if (Source != null)
            {
                binding.Source = Source;
            }
            var expr = BindingOperations.SetBinding(targetObject, ResourceReferenceProperty, binding);

            var descriptor = DependencyPropertyDescriptor.FromProperty(ResourceReferenceProperty, targetObject.GetType());
            descriptor.AddValueChanged(targetObject, (s, e) =>
            {
                // 中継した値を取得してリソースへの参照を作成
                var changeKey = targetObject.GetValue(ResourceReferenceProperty);
                var newDre = new DynamicResourceExtension(changeKey);
                targetObject.SetValue(targetProperty, newDre.ProvideValue(new ServiceValueProvider()));
            });

            // 初期値を作るための更新
            //   Prism の ViewModelLocator のような InitializeComponent 内で ViewModel を生成し DataContext に設定している場合は以下の処理が必要となる
            //   そうでない場合は return null で問題なく動く
            expr.UpdateSource();

            // 初期表示にはこの参照が使用される
            var key = targetObject.GetValue(ResourceReferenceProperty);

            if (key != null)
            {
                var dre = new DynamicResourceExtension(key);
                return dre.ProvideValue(new ServiceValueProvider());
            }

            return null;
        }

        /// <summary>
        /// バインディング情報を生成する。
        /// </summary>
        /// <returns></returns>
        private Binding CreateBinding()
        {
            var baseBinding = new Binding
            {
                Path = Path,
                XPath = XPath,
                Mode = Mode,
                UpdateSourceTrigger = UpdateSourceTrigger
            };

            if (RelativeSource != null)
            {
                baseBinding.RelativeSource = RelativeSource;
            }

            if (ElementName != null)
            {
                baseBinding.ElementName = ElementName;
            }

            if (Source != null)
            {
                baseBinding.Source = Source;
            }

            return baseBinding;
        }
    }

    /// <summary>
    /// DynamicResource を C# コードで指定するために使用するクラス。
    /// </summary>
    public class ServiceValueProvider : IServiceProvider, IProvideValueTarget
    {
        public object TargetObject { get; private set; }

        public object TargetProperty { get; private set; }

        public object GetService(Type serviceType)
        {
            if (serviceType == typeof(IProvideValueTarget))
            {
                return this;
            }
            return null;
        }

        internal void SetData(object targetObject, object targetProperty)
        {
            TargetObject = targetObject;
            TargetProperty = targetProperty;
        }
    }
}

C# で USB メモリの情報を取得する

ManagementObjectSearcher を使用する。(System.Management.dll の参照が必要)

var mos = new ManagementObjectSearcher("Select * from Win32_DiskDrive where InterfaceType='USB'");
// SELECT * FROM Win32_PnPEntity where DeviceID Like 'USB%' 

foreach (var mo in mos.Get())
{
    Console.WriteLine(mo);

    foreach (var prop in mo.Properties)
    {
        Console.WriteLine($"  {prop.Name} : {prop.Value}");
    }
    //インデクサで個別取得できる
    //var pnp = mo["PNPDeviceID"].ToString();
    //Console.WriteLine(pnp);
}

屋号のみの口座を開設する方法

目標

屋号のみの口座を開設する。

前提

開業届提出済みであること。

手順

印鑑登録

市役所などで印鑑登録が必要です。

商号登記

法務局にて商号登記が必要となります。登記に必要なものは以下の通りです:

  • ↑で登録した印鑑と印鑑証明書
  • 印鑑届出書(法務局でもらえます)
  • 商号登記申請書(自分で作成します。サンプルはもらえます)
  • 30,000分の収入印紙(法務局で購入できます)

口座開設

メガバンクでは屋号のみの口座は作成できないようです。ゆうちょでは振替口座であれば作成可能ですが、開設に審査が必要になることと、振替に手数料がかかることがネックです。周りの方の紹介で、私は農協で口座を作成しました。口座作成に必要になったものは以下の通りです:

  • 登記事項証明書(法務局で申請します)
  • 印鑑カード(法務局で作成します)
  • ↑の印鑑カードを使用して申請した印鑑証明書(法務局で作成します)
  • その他、口座開設に必要な書類

以上を経て、屋号のみの口座を開設できました。地方銀行をあたってみるのがいいと思います。