Note that there are some explanatory texts on larger screens.

plurals
  1. PODependency Property in User Control works only on the first instance
    text
    copied!<p>I have several custom user controls in a window. They appear dynamically, like workspaces. I need to add a dependency property on an itemscontrol to trigger a scrolldown when an item is being added to the bound observable collection to my itemscontrol, like so: (usercontrol)</p> <pre><code>&lt;ScrollViewer VerticalScrollBarVisibility="Auto" &gt; &lt;ItemsControl Grid.Row="0" ItemsSource="{Binding Messages}" View:ItemsControlBehavior.ScrollOnNewItem="True"&gt; &lt;ItemsControl.ItemTemplate&gt; &lt;DataTemplate&gt; &lt;TextBox IsReadOnly="True" TextWrapping="Wrap" Text="{Binding Path=DataContext, RelativeSource={RelativeSource Self}}" /&gt; &lt;/DataTemplate&gt; &lt;/ItemsControl.ItemTemplate&gt; &lt;/ItemsControl&gt; &lt;/ScrollViewer&gt; </code></pre> <p>And the code of my dependency property : </p> <pre><code> public class ItemsControlBehavior { static readonly Dictionary&lt;ItemsControl, Capture&gt; Associations = new Dictionary&lt;ItemsControl, Capture&gt;(); public static bool GetScrollOnNewItem(DependencyObject obj) { return (bool)obj.GetValue(ScrollOnNewItemProperty); } public static void SetScrollOnNewItem(DependencyObject obj, bool value) { obj.SetValue(ScrollOnNewItemProperty, value); } public static readonly DependencyProperty ScrollOnNewItemProperty = DependencyProperty.RegisterAttached( "ScrollOnNewItem", typeof(bool), typeof(ItemsControl), new UIPropertyMetadata(false, OnScrollOnNewItemChanged)); public static void OnScrollOnNewItemChanged( DependencyObject d, DependencyPropertyChangedEventArgs e) { var mycontrol = d as ItemsControl; if (mycontrol == null) return; bool newValue = (bool)e.NewValue; if (newValue) { mycontrol.Loaded += new RoutedEventHandler(MyControl_Loaded); mycontrol.Unloaded += new RoutedEventHandler(MyControl_Unloaded); } else { mycontrol.Loaded -= MyControl_Loaded; mycontrol.Unloaded -= MyControl_Unloaded; if (Associations.ContainsKey(mycontrol)) Associations[mycontrol].Dispose(); } } static void MyControl_Unloaded(object sender, RoutedEventArgs e) { var mycontrol = (ItemsControl)sender; Associations[mycontrol].Dispose(); mycontrol.Unloaded -= MyControl_Unloaded; } static void MyControl_Loaded(object sender, RoutedEventArgs e) { var mycontrol = (ItemsControl)sender; var incc = mycontrol.Items as INotifyCollectionChanged; if (incc == null) return; mycontrol.Loaded -= MyControl_Loaded; Associations[mycontrol] = new Capture(mycontrol); } class Capture : IDisposable { public ItemsControl mycontrol{ get; set; } public INotifyCollectionChanged incc { get; set; } public Capture(ItemsControl mycontrol) { this.mycontrol = mycontrol; incc = mycontrol.ItemsSource as INotifyCollectionChanged; incc.CollectionChanged +=incc_CollectionChanged; } void incc_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Add) { ScrollViewer sv = mycontrol.Parent as ScrollViewer; sv.ScrollToBottom(); } } public void Dispose() { incc.CollectionChanged -= incc_CollectionChanged; } } } </code></pre> <p>During the first instantiation of my user control, it works like a charm. But when another user control of the same type is dynamically instantiated, the DependencyProperty is never attached anymore to my scrollviewer. Only the first instance will work correctly. I know that dependency properties are static, but does that mean they can't work at the same time on several user control of the same type added to the window? </p> <p>Update 02/03 : Here's how I set the viewmodel to the view (not programmatically) : </p> <pre><code> &lt;ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="clr-namespace:testDp.ViewModel" xmlns:View="clr-namespace:testDp.View"&gt; &lt;DataTemplate DataType="{x:Type vm:ChatTabViewModel}"&gt; &lt;View:ChatTabView /&gt; &lt;/DataTemplate&gt; &lt;/ResourceDictionary&gt; </code></pre> <p>even with x:shared = false in the datatemplate tag, it won't work. But if I set the datacontext in a classic way like usercontrol.datacontext = new viewmodel(), it definitely work. But it's recommended to have a "shared" view, so how do we make dependency properties work with this "xaml" way of setting datacontext ?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload