2016-07-14 80 views
0

這是不工作的權利:綁定菜單項來器isChecked設置

<MenuItem x:Uid="MenuItem_12" Header="400%" IsCheckable="True" 
      IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsValidZoomFactor}, ConverterParameter='400'}"/> 

在我Settings我有一個整數ZoomFactor。設置設置爲公開和範圍用戶

在我的XAML的頂部我有一個命名空間:

xmlns:Properties="clr-namespace:OCLMEditor.Properties" 

這是我ValueConverter

using System; 
using System.Globalization; 
using System.Windows.Data; 

namespace OCLMEditor.ValueConverters 
{ 
    [ValueConversion(typeof(int), typeof(bool))] 
    public class IsCurrentZoomFactor : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      int desiredZoomFactor = (int)value; 
      int currentZoomFactor = (int)parameter; 

      return desiredZoomFactor == currentZoomFactor; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 

但我得到一個錯誤:

1>D:\My Programs\OCLMEditor\OCLMEditor\MainWindow.xaml(143,35): error MC3044: The text '}' is not allowed after the closing '}' of a MarkupExtension expression. Line 143 Position 35.

我有其他幾個菜單項:

<MenuItem x:Uid="MenuItem_13" Header="300%" IsCheckable="True"/> 
<MenuItem x:Uid="MenuItem_14" Header="250%" IsCheckable="True"/> 
<MenuItem x:Uid="MenuItem_15" Header="200%" IsCheckable="True"/> 
<MenuItem x:Uid="MenuItem_16" Header="175%" IsCheckable="True"/> 
<MenuItem x:Uid="MenuItem_17" Header="150%" IsCheckable="True"/> 
<MenuItem x:Uid="MenuItem_18" Header="125%" IsCheckable="True"/> 

我不知道我要對這個正確的方式,但這個想法是:

  1. 傳遞Settings.ZoomFactor價值的轉換器。
  2. 將預期的縮放係數值傳遞給轉換器。
  3. 將它們兩者進行比較,如果它們相同,則將其設置爲檢查。

此外,此刻它被「改變」,所以另一個縮放因子,設置被更新。我認爲對「環境」的約束是正確的路要走。但有錯誤。

我確認錯誤是在IsChecked行:

Editor

更新錯誤:

Error

自身此位無視覺誤差:

<MenuItem x:Uid="MenuItem_12" Header="400%" IsCheckable="True" 
      IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor}"/> 

所以它是轉換器/值的介紹,它出錯了。

現在,我不得不改變我的轉換器:

using System; 
using System.Globalization; 
using System.Windows.Data; 

namespace OCLMEditor.ValueConverters 
{ 
    [ValueConversion(typeof(int), typeof(bool))] 
    public class IsCurrentZoomFactor : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      int currentZoomFactor = (int)value; 
      string strDesiredZoomFactor = (string)parameter; 
      int desiredZoomFactor = int.Parse(strDesiredZoomFactor); 
      return desiredZoomFactor == currentZoomFactor; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 

因爲我們傳遞「400」這是一個字符串。所以我必須將其轉換爲整數。如果我刪除了'',它不會接受將它作爲整數傳遞。

+0

是否確定菜單項是什麼就行143 /位置35?該錯誤表示在綁定或其他方面存在孤立關閉花括號:'Foo =「{Binding Bar}}」'例如 –

+0

@EdPlunkett花括號確實是正確的。 –

+0

他們確實顯示正確。這不是單引號,他們在你有他們的地方都很好。沒有別的東西在那邊,對嗎?你是否清理解決方案,重新啓動VS並構建?當XAML編輯似乎正在失去主意時,總是值得嘗試。 –

回答

1

似乎這裏的麻煩與Binding.ConverterParameter是一個字符串有關,因爲XAML解析器無法知道期望的類型。

這是一種用強類型參數(或多個參數,如果你喜歡)重寫你的值轉換器的方法。如果您可以將參數類型檢查從代碼中的運行時錯誤移動到IDE中的設計時間消息,那永遠都是贏。

public class IsCurrentZoomFactor : MarkupExtension, IValueConverter 
{ 
    public int DesiredZoomFactor { get; set; } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return this; 
    } 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     int currentZoomFactor = (int)value; 
     return DesiredZoomFactor == currentZoomFactor; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

並且像這樣使用它。請注意,我們並未創建IsCurrentZoomFactor作爲資源的實例。由於它是MarkupExtension,因此我們將它實例化,並在其中初始化其參數屬性。這樣做的好處是XAML解析器知道DesiredZoomFactor是一個整數。因爲它使價值轉換的自我記錄

<MenuItem 
    x:Uid="MenuItem_12" Header="400%" IsCheckable="True" 
    IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={local:IsCurrentZoomFactor DesiredZoomFactor=400}}" 
    /> 

這是非常方便的:

你會這樣使用它。當您在XAML類型{local:IsCurrentZoomFactor,XAML編輯器讓你的屬性列表:

enter image description here

猛打試圖記住什麼參數是,半年,兩年你寫的轉換器之後。如果房產類型是enum,您甚至會得到一個可供選擇的值列表。

順便說一句,我會重命名此轉換器和它的參數,以反映一個事實,即它是真正做的是返回true,如果一個整數等於另:

Converter={local:IsIntegerEqual To=400} 
1

你的問題是ConverterParameter。寫參數,而不喜歡

... ConverterParameter=400}"/> 

aditional的一撇,你必須使用一個轉換爲得到這樣

int desiredZoomFactor = Convert.ToInt16(value); 
+0

謝謝。如果我刪除了apostraphe,現在它告訴我在輸出窗口中「指定的演員無效」。 –

+0

你能發佈一個screeshot嗎? – Fruchtzwerg

+0

我已添加屏幕截圖。 –

0

感謝您的幫助整數值。我現在有這個工作。

所以該轉換器看起來像這樣:

using System; 
using System.Globalization; 
using System.Windows.Data; 

namespace OCLMEditor.ValueConverters 
{ 
    [ValueConversion(typeof(int), typeof(bool))] 
    public class IsCurrentZoomFactor : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      int currentZoomFactor = (int)value; 
      string strDesiredZoomFactor = (string)parameter; 
      int desiredZoomFactor = int.Parse(strDesiredZoomFactor); 
      return desiredZoomFactor == currentZoomFactor; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      return int.Parse((string)parameter); 
      //throw new NotImplementedException(); 
     } 
    } 
} 

而XAML:

<MenuItem x:Uid="MenuItem_12" Header="400%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='400'}"/> 
<MenuItem x:Uid="MenuItem_13" Header="300%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='300'}"/> 
<MenuItem x:Uid="MenuItem_14" Header="250%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='250'}"/> 
<MenuItem x:Uid="MenuItem_15" Header="200%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='200'}"/> 
<MenuItem x:Uid="MenuItem_16" Header="175%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='175'}"/> 
<MenuItem x:Uid="MenuItem_17" Header="150%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='150'}"/> 
<MenuItem x:Uid="MenuItem_18" Header="125%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='125'}"/> 
<MenuItem x:Uid="MenuItem_19" Header="100%" IsCheckable="True" InputGestureText="CTRL + 0" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='100'}"> 
    <MenuItem.InputBindings> 
     <KeyBinding x:Uid="KeyBinding_9" Key="D0" Modifiers="Ctrl"/> 
    </MenuItem.InputBindings> 
</MenuItem> 
<MenuItem x:Uid="MenuItem_20" Header="75%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='75'}"/> 
<MenuItem x:Uid="MenuItem_21" Header="50%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='50'}"/> 
<Separator x:Uid="Separator_8"/> 
<MenuItem x:Uid="MenuItem_22" Header="Custom..."/> 

至少現在設置正確保存。我知道我有更多的工作要做(比如將點擊綁定到命令)。