我在窗口中有幾個自定義用戶控件。它們動態顯示,如工作區。 我需要在一個ItemsControl添加一個依賴屬性觸發,當一個項目被添加到綁定的觀察集合到我的ItemsControl,像這樣一個下滾: (用戶控件)用戶控件中的依賴屬性僅適用於第一個實例
<ScrollViewer VerticalScrollBarVisibility="Auto" >
<ItemsControl Grid.Row="0" ItemsSource="{Binding Messages}" View:ItemsControlBehavior.ScrollOnNewItem="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox IsReadOnly="True" TextWrapping="Wrap" Text="{Binding Path=DataContext, RelativeSource={RelativeSource Self}}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
和我相依的代碼物業:
public class ItemsControlBehavior
{
static readonly Dictionary<ItemsControl, Capture> Associations =
new Dictionary<ItemsControl, Capture>();
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;
}
}
}
在我的用戶控件的第一個實例化,它像一個魅力。 但是,當同一類型的另一個用戶控件被動態實例化時,DependencyProperty不再附加到我的滾動查看器中。只有第一個實例才能正常工作。 我知道依賴項屬性是靜態的,但這是否意味着它們不能同時添加到窗口中的同一類型的多個用戶控件上?
更新02/03:以下是我的視圖模型設置爲視圖(未編程):
<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">
<DataTemplate DataType="{x:Type vm:ChatTabViewModel}">
<View:ChatTabView />
</DataTemplate>
</ResourceDictionary>
即使X:在DataTemplate中標記共享= false時,將無法正常工作。 但是,如果我以像usercontrol.datacontext = new viewmodel()這樣的經典方式設置datacontext,它肯定有效。但建議有一個「共享」視圖,那麼我們如何使用這種「xaml」設置datacontext的方式來使依賴項屬性工作?
您在DependencyProperty創建中的第二個typeof應該是所有者類的類型,但是您提供了ItemsControl,將其更改爲ItemsControlBehavior。但我不認爲這是造成你的問題。 – dowhilefor 2012-02-02 22:05:52
我的不好...謝謝。不幸的是,問題仍然存在...... – KitAndKat 2012-02-02 22:11:01
我可以看到兩個靜態函數充當get/set。爲什麼不按照約定使用屬性包裝器來處理dependencyproperty? – Jimmy 2012-02-03 10:33:26