近くに行くアウトとプロパティとして公開されます、私は彼らの提案で私を助けた皆に感謝伝えたいです溶液を見つける。 私はSilentDictionary
クラスを作成し、Dictionary
の代わりにそれを使用しています
public class SilentDictionary<TKey, TValue> : IDictionary<TKey, TValue>
where TValue : class, new()
{
protected IDictionary<TKey, TValue> Dictionary;
public SilentDictionary()
{
Dictionary = new Dictionary<TKey, TValue>();
}
public TValue this[TKey key]
{
get
{
TValue item;
if (Dictionary.TryGetValue(key, out item))
return item;
else
{
item = new TValue();
Add(key, item);
return item;
}
}
set
{
Add(key, value);
}
}
public int Count
{
get
{
return Dictionary.Count;
}
}
public bool IsReadOnly
{
get
{
return Dictionary.IsReadOnly;
}
}
public ICollection<TKey> Keys
{
get
{
return Dictionary.Keys;
}
}
public ICollection<TValue> Values
{
get
{
return Dictionary.Values;
}
}
public void Add(KeyValuePair<TKey, TValue> item)
{
Add(item.Key, item.Value);
}
public void Add(TKey key, TValue value)
{
TValue item;
if (Dictionary.TryGetValue(key, out item))
{
Type t = typeof(TValue);
var props = t.GetProperties();
foreach (var p in props)
p.SetValue(item, p.GetValue(value));
}
else
Dictionary.Add(key, value);
}
public void Clear()
{
Dictionary.Clear();
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
return Dictionary.Contains(item);
}
public bool ContainsKey(TKey key)
{
return Dictionary.ContainsKey(key);
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
Dictionary.CopyTo(array, arrayIndex);
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return Dictionary.GetEnumerator();
}
public bool Remove(KeyValuePair<TKey, TValue> item)
{
return Dictionary.Remove(item);
}
public bool Remove(TKey key)
{
return Dictionary.Remove(key);
}
public bool TryGetValue(TKey key, out TValue value)
{
return Dictionary.TryGetValue(key, out value);
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)Dictionary).GetEnumerator();
}
}
InitializeComponent
が進行しているときに例外がスローされていません。このクラスの主なアイデア。それは私にバインディングがそれから価値を得ることを試みる前に辞書のインスタンスを作成する機会を与えます。これはメインウィンドウのコンストラクタで行われていることです:
public MainWindow()
{
ViewModelBase.Permissions = new SilentDictionary<string, Action>();
InitializeComponent();
}
今すぐバインディングにはDependencyProperty.UnsetValue
がありません。バインディングは私の静的なSilentDictionary
インスタンスとの接続を持っています。次のステップは、静的辞書のプロパティの変更を通知することです:
public abstract class ViewModelBase
{
protected static SilentDictionary<string, Action> _permissions;
public static SilentDictionary<string, Action> Permissions
{
get { return _permissions; }
set
{
_permissions = value;
NotifyPropertyChanged();
}
}
public static event EventHandler PermissionsChanged;
protected static void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
EventHandler temp = Volatile.Read(ref PermissionsChanged);
PermissionsChanged?.Invoke(null, new EventArgs());
}
// other code
}
と私は初めに計画通り、最終的に、私はこの辞書にバインドすることができます。
<MenuItem x:Name="systemMenuItem" Header="Система" Visibility="{Binding Permissions[systemMenuItem].CanBeShown, Converter={StaticResource BoolToVis}}">
そして、すべてが期待どおりにうまく動作します。
変更可能な辞書にバインドする場合は、バインド可能な辞書の実装を使用する必要があります。 –
@HB:http://blogs.microsoft.co.il/shimmy/2010/12/26/observabledictionarylttkey-tvaluegt-c/ – Kilazur
で展開するとわかりましたが、結果は同じです。私はちょうど辞書のタイプを変更して、他はすべて同じです。バインディングは 'Loaded'ではまだ動作しておらず、' InitializeComponent() 'の前にObservableDictionaryを作成している場合は例外がスローされます。 –