Динамическое добавление объектов в ComboBox и на Canvas в WPF
ComboBox cBox = new ComboBox();
canvas.Children.Add(cBox);
UserControl usercontrol = new UserControl();
usercontrol.Name = "fr1";
Devices.Add(usercontrol.Name, usercontrol);
canvas.Children.Add(usercontrol);
Binding binding = new Binding();
binding.Mode = BindingMode.OneWay;
binding.Source = this.Devices;
binding.Path = new PropertyPath("Values");
cBox.SetBinding(ComboBox.ItemsSourceProperty, binding);
Теперь при раскрытии списка cBox появляется исключение NullReferenceException. А если убрать строку: canvas.Children.Add(usercontrol);, то все работает гладко. Получается нельзя добавлять один и тот же объект и в хештайбл и на канвас. Это можно как-то обойти?
дело не хэштэйбле и не в канвасе. дело в том как создаётся usercontrol. предполагаю что класс UserControl предназначен для наследования а не для прямого инстанцирования
так и есть. у меня есть класс, наследованный от UserControl. В проге я делаю примерно так:
{ ... }
...
UserControl usercontrol = new MyClass();
//и т.д.
Сначала я думал, что дело в моем классе и сделал проще - заменил MyClass на UserControl.
Но все равно не работает ни так, ни так.
в System.Windows.Controls.Primitives.Popup.OnWindowResize(Object sender, AutoResizedEventArgs e)
в System.Windows.Interop.HwndSource.Resize(Size newSize)
в System.Windows.Interop.HwndSource.OnLayoutUpdated(Object obj, EventArgs args)
в System.Windows.ContextLayoutManager.fireLayoutUpdateEvent()
в System.Windows.ContextLayoutManager.UpdateLayout()
в System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
в System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()
в System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
в System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
в System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
в System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
в System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
в System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
в System.Windows.Threading.DispatcherOperation.InvokeImpl()
в System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
в System.Threading.ExecutionContext.runTryCode(Object userData)
в System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
в System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
в System.Windows.Threading.DispatcherOperation.Invoke()
в System.Windows.Threading.Dispatcher.ProcessQueue()
в System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
в MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
в MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
в System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
в System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
в System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
в System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
в System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
в MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
в MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
в System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
в System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
в System.Windows.Threading.Dispatcher.Run()
в System.Windows.Application.RunDispatcher(Object ignore)
в System.Windows.Application.RunInternal(Window window)
в System.Windows.Application.Run(Window window)
в System.Windows.Application.Run()
в WpfApplication2.App.Main() в D:\Программирование\C#\Projects\WpfApplication2\WpfApplication2\obj\Debug\App.g.cs:строка 0
в System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
в System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
в Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
в System.Threading.ThreadHelper.ThreadStart_Context(Object state)
в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
в System.Threading.ThreadHelper.ThreadStart()
второй вариант отпадает сразу. а вот первый - все бы хорошо, только канвасов будет несколько, а в комбобоксе должны появиться все со всех канвасов.
canvas.Children.Add(usercontrol);
ComboBox cBox = new ConboBox();
Binding binding = new Binding();
binding.Source = this.canvas;
binding.Path = new PropertyPath("Children");
cBox.SetBinding(ComboBox.ItemsSourceProperty, binding);
Последняя строка не срабатывает. Можно добавить
Как-то у вас все тяжело :) Можете в кратце описать задачу, которую пытаетесь решить?
есть несколько устройств (наследованы от UserControl) и отдельных "компонентов". каждый компонент должен быть привязан к одному устройству. причем несколько компонентов может ссылаться на одно устройство. в настройках компонента должен появляться комбобокс со всеми устройствами для выбора привязки к устройству. вот мне и надо как-то формировать комбобокс
lstControls.Add(new UserControl(){Name = "Test"});
ComboBox cmb = new ComboBox();
Binding binding= new Binding
{
ItemSsource = lstControls
};
cmd.DisplayMemberPath = "Name";
cmb.SetBinding(ComboBox.ItemsSourceProperty, binding);
foreach(UserControl userControl in lstControls)
canvas.Add(userControl);
Либо:
СomboBox cmb = new ComboBox();
Binding binding= new Binding
{
ItemsSource = canvas.Children
};
cmd.DisplayMemberPath = "Name";
cmb.SetBinding(ComboBox.ItemsSourceProperty, binding);
Может там где-то и ошибки допущены, пишу без студии, но суть уловить можно :)
будет отображаться только имя. а мне надо, чтоб сам usercontrol
Ищите где он.
А если DisplayMemberPath = "Name" - то что-то отображается или пустота?
У меня такой же глюк был. При выбранном элементе ниче не отображается. Попробуйте добавить еще и SelectedValuePath - это должно помочь решить проблему с отображением.
У вас к комбобоксе никогда не будет отображаться userControl. Рисуйте его представление и используйте DisplayMemberPath, SelectedValuePath.
Надеюсь это поможет.