2017-04-05 50 views
2

我環顧四周,但仍然無法找到解決的辦法......用戶控件綁定到的ObservableCollection不工作

我做了一個UserControl這基本上是一個滑塊,但幾乎沒有自定義功能。

public partial class CustomSlider : UserControl 
{ 
    public CustomSlider() 
    { 
     InitializeComponent(); 
     this.DataContext = this; 

     CMiXSlider.ApplyTemplate(); 
     Thumb thumb0 = (CMiXSlider.Template.FindName("PART_Track", CMiXSlider) as Track).Thumb; 
     thumb0.MouseEnter += new MouseEventHandler(thumb_MouseEnter); 
    } 

    private void thumb_MouseEnter(object sender, MouseEventArgs e) 
    { 
     if (e.LeftButton == MouseButtonState.Pressed && e.MouseDevice.Captured == null) 
     { 
      MouseButtonEventArgs args = new MouseButtonEventArgs(e.MouseDevice, e.Timestamp, MouseButton.Left); 
      args.RoutedEvent = MouseLeftButtonDownEvent; 
      (sender as Thumb).RaiseEvent(args); 
     } 
    } 

    public static readonly DependencyProperty ValueProperty = 
    DependencyProperty.Register("Value", typeof(double), typeof(CustomSlider), new PropertyMetadata(0.0)); 
    public double Value 
    { 
     get { return (double)this.GetValue(ValueProperty); } 
     set { this.SetValue(ValueProperty, value); } 
    } 
} 

的XAML:

<UserControl x:Class="CMiX.CustomSlider" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:local="clr-namespace:CMiX" 
     mc:Ignorable="d" 
     d:DesignHeight="139.8" d:DesignWidth="546.2"> 
<UserControl.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="/CMiX_UserControl;component/RessourceDictionnaries/Brushes/GenericBrushes.xaml"/> 
      <ResourceDictionary Source="/CMiX_UserControl;component/RessourceDictionnaries/Styles/BaseSliderStyle.xaml"/> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</UserControl.Resources> 
<Grid> 
    <Slider x:Name="CMiXSlider" Style="{StaticResource BaseSliderStyle}" 
      Value="{Binding Value, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type local:CustomSlider}}}" 
      IsMoveToPointEnabled="True" Minimum="0.0" Maximum="1.0"/> 
</Grid> 

然後我用這裏面的另一個UserControl像這樣:

<CMiX:CustomSlider x:Name="SliderTest" Grid.Row="2" Value="{Binding ChannelsAlpha[0], Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 

而且我試圖綁定到這個ObservableCollection(中相同的滑塊將被使用6次):

private ObservableCollection<double> _ChannelsAlpha = new ObservableCollection<double>(new[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }); 
    public ObservableCollection<double> ChannelsAlpha 
    { 
     get { return _ChannelsAlpha; } 
     set { _ChannelsAlpha = value; } 
    } 

問題是,綁定不會以任何方式發生。而我特別沒有得到的是,如果我使用這個標準滑塊:

<Slider x:Name="Ch0_Alpha" Margin="1" IsMoveToPointEnabled="True" Minimum="0.0" Maximum="1.0" Orientation="Horizontal" Value="{Binding DataContext.ChannelsAlpha[0], ElementName=Ch0_Alpha, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 

然後它按預期工作。

回答

3

您不能綁定到任何東西,因爲你很仔細地打破了你的DataContext:

this.DataContext = this; 

不要那樣做。綁定到用戶控件本身的屬性,使用的RelativeSource綁定,就像......就像你已經使用了一個:

<Slider 
    x:Name="CMiXSlider" 
    Style="{StaticResource BaseSliderStyle}" 
    Value="{Binding Value, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type local:CustomSlider}}}" 
    IsMoveToPointEnabled="True" 
    Minimum="0.0" 
    Maximum="1.0" 
    /> 

我沒有看到任何你正在使用的用戶控件XAML內DataContext的,所以我只是在構造函數中刪除那行,然後去喝啤酒。

嗯,首先,對好表的緣故,我想擺脫在構造函數模板的東西,並將其移動到OnApplyTemplate:

public CustomSlider() 
{ 
    InitializeComponent(); 
} 

public override void OnApplyTemplate() 
{ 
    Thumb thumb0 = (CMiXSlider.Template.FindName("PART_Track", CMiXSlider) as Track).Thumb; 
    thumb0.MouseEnter += new MouseEventHandler(thumb_MouseEnter); 
} 

然後啤酒。

P.S.下面是如何調試綁定:

Value="{Binding ChannelsAlpha[0], PresentationTraceSources.TraceMode=High, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 

添加PresentationTraceSources.TraceMode=High,然後看在VS輸出窗口在運行。它會告訴你嘗試解決綁定所需的所有步驟。在這種情況下它會告訴你的是,它在CMiX:CustomSlider的實例上尋找ChannelIsAlpha而不是在視圖模型上。這是你的線索,該問題是通過擺脫DataContext的繼承值而創建的。在您的構造函數中,this.DataContext是父視圖的視圖模型,直到您將它設置爲this(在斷點處彈出並查看)。

這就是爲什麼我們一些胡思亂想的老人有這樣一個毛刺關於不設置this.DataContext = this;。首先你在相對無害的情況下做這件事,然後你開始認爲這只是必要的樣板,而現在就是這樣。實際上,它的從不需要

綁定和DataContext是很痛苦的習慣,因爲有這種隱含的事情發生。起初我發現它很奇怪。請記住,假設默認情況下,所有綁定都將綁定到視圖模型,並且您應該始終能夠假設無論您身在何處,DataContext都將成爲視圖模型。並且從不明確設置DataContext

綁定到任何東西,但視圖模型是一種特殊情況:RelativeSource={RelativeSource AncestorType=FooBar}Source={StaticResource WhateverKey}ElementName=FooBarListBoxRelativeSource={RelativeSource Self},或什麼的。

+0

在一個用戶控件中,initializecomponent應用模板,所以它不會改變任何東西。 – briantyler

+0

@briantyler這就是爲什麼我說「爲了好形式」。 –

+0

好的一切工作正常,謝謝我學習新的東西。但是,你介意告訴我更多爲什麼this.DataContext = this;打破了數據上下文。我認爲我正在定義它......謝謝 – lecloneur

相關問題