2015-04-07 130 views
0

我正在爲WYSIWYG HTML編輯器控制Ribbon控件。功能區具有您期望看到的典型Bold,Italic,Underline,FontFamily等控件。我將專注於此示例的Bold功能。WPF ::自定義控件的依賴項屬性不起作用

我想Ribbon是可重複使用的,所以我添加了一個依賴項屬性(DP)和相關屬性包裝到控件的代碼後面(標準的樣板東西):

public partial class EditorRibbon: UserControl 
{ 
    public static readonly DependencyProperty IsBoldProperty = 
    DependencyProperty.Register(
    "IsBold", 
    typeof (bool), 
    typeof (EditorRibbon), 
    new PropertyMetadata(default(bool))); 

    public bool IsBold 
    { 
    get { return (bool) GetValue(IsBoldProperty); } 
    set { SetValue(IsBoldProperty, value); } 
    } 
} 

...和在XAML我有我RibbonToggleButton,我已經綁定的IsChecked屬性依賴屬性:

<UserControl x:Class="My.EditorRibbon"> 
    <r:RibbonToggleButton Command="ToggleBold" 
         ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}" 
         SmallImageSource="{StaticResource ToggleBoldIcon}" 
         IsChecked="{Binding IsBold}" /> 

</UserControl> 

在我Editor窗口,我已經綁定的0123的IsBold財產對窗口的視圖模型的常規屬性:

<Window x:class="My.MainWindow> 
    <My.EditorRibbon IsBold="{Binding SelectionIsBold}"/> 
</Window> 

這裏是SelectionIsBold屬性:

public bool SelectionIsBold 
{ 
    get { return _selection.IsBold(); } 
} 

...我提高NotifyPropertyChanged()事件(在主窗口的視圖模型),只要在選擇RichTextBox變化:

public class MainWindowViewModel : BaseViewModel 
{ 
    public MainWindowViewModel(MainWindow window) 
    { 
     rtb.SelectionChanged += rtb_OnSelectionChanged; 
    } 

    private void rtb_OnSelectionChanged(object sender, RoutedEventArgs routedEventArgs) 
    { 
     NotifyPropertyChanged(()=>SelectionIsBold); 
    } 

} 

在我看來,這應該是足以改變IsChecked統計每當選擇發生變化時,RibbonToggleButton的電子郵件都會被刪除,但事實並非如此。儘管改變了選擇,並且儘管NotifyPropertyChanged()如預期的那樣射擊,SelectionIsBold屬性的斷點(是的,我已經取消選擇VS的「Step Over Property」設置)從未被擊中。某處,刷新該值的請求無法正確傳播。

在setter中設置值之後,是否需要在IsBold屬性上觸發NotifyPropertyChanged()?

+0

難道你不需要綁定你的命令嗎? Command =「{Binding ToggleBold}」 –

+0

其中是'rtb_OnSelectionChanged' – Neil

+0

@Neil - rtb_OnSelectionChanged在包含RichTextBox和EditorRibbon的窗口中。 –

回答

0

更改IsBold結合以下

<UserControl x:Class="My.EditorRibbon" x:Name="EditorRibbonInstance"> 
<r:RibbonToggleButton Command="ToggleBold" 
        ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}" 
        SmallImageSource="{StaticResource ToggleBoldIcon}" 
        IsChecked="{Binding IsBold, ElementName=EditorRibbonInstance, Mode=TwoWay}" /> 
</UserControl> 

與要確保

+0

我試過了,沒有快樂 - 有些東西還不行。選擇更改時,IsChecked屬性仍然不會更新。 –

+0

我忘了添加模式TwoWay,試一試 –

+0

爲什麼會是TwoWay? IsChecked屬性沒有在任何地方推送它的值 - 它嚴格從選擇中讀取。無論哪種方式,它都不起作用。 –

-1

你是不是正確的結合是要控制的財產,未對控件的DataContext的綁定你的按鈕的命令屬性。

應該反映這樣的事:

Command="{Binding ToggleBold}" 
+0

我恭敬地不同意。 ToggleBold命令完美運行。該按鈕在CanExecute()失敗時禁用,Execute()方法完全按照廣告切換粗體。唯一不工作的部分是接線IsChecked以反映當前的選擇。 –

+0

好的。我不知道你可以給一個命令屬性分配一個字符串值,而不用綁定語法儀式。 –

+0

就這麼你知道,這不是我低估了你。 :-) –

0

你必須在視圖模型火notifypropertychanged。試着這樣出頭的視圖模型:

protected void FirePropertyChanged(string propertyName) 
    { 
     if (this.PropertyChanged != null) 
     { 
      this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 


->> FirePropertyChanged("SelectionIsBold") 

原因是:現在,您的數據上下文爲視圖模型,所有的結合視圖模型必須由視圖模型的屬性

+0

我將我的訂閱移到了ViewModel的事件和事件處理程序中,但仍然沒有什麼喜悅。我正在更新我的帖子以反映這一點。 –

+0

讓我嘗試用我的更新的答案 – Neil

+0

我的NotifyPropertyChanged(()=> SelectionIsBold)方法做到這一點,它只是使用反射而不是字符串來獲取屬性名稱。 –

0

首先來觸發,我從來沒有見過注射窗口到ViewModel之前......你是否在使用某種DI進行注入?

我認爲這是不使用選擇一個好主意,改變了事件的視圖模型......這不是從我的角度來看MVVM ...

你某處更新_selection?可能是你總是檢查相同的選擇?!

相關問題