2011-05-09 117 views
3

我試圖在列表視圖上顯示可用的Wifi網絡(使用ManagedWifi SDK)。WPF - MVVM - 從視圖模型返回可綁定控制模板

我已經定義WifiNetwork的的ObservableCollection(包含名稱,類型,信號強度(INT)等)如下所示

public ObservableCollection<WifiNetwork> AvailableNetworks { get; set; } 

我已經定義控制模板(如1-綠色條和4個白條在我的視圖模型指示信號強度< = 20%,2個綠色條和3個白條以指示App.xaml中20%至40%等)的應用程序資源之間的信號強度如下所示

<ControlTemplate x:Key="Signal1"> 
    <Canvas Width="32" Height="32" Canvas.Left="0" Canvas.Top="0"> 
     <Rectangle Width="5.4375" Height="11.375" Canvas.Left="0.0937499" Canvas.Top="20.6563" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF37F307"/> 
     <Rectangle Width="6.40625" Height="16" Canvas.Left="5.34375" Canvas.Top="16.0313" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF"/> 
     <Path Width="6.88835" Height="21.6562" Canvas.Left="11.75" Canvas.Top="10.375" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF" Data="F1 M 12.2768,10.875L 18.1384,10.875L 18.1115,31.5313L 12.25,31.5313L 12.2768,10.875 Z "/> 
     <Rectangle Width="6.78126" Height="26.9687" Canvas.Left="18.5625" Canvas.Top="5.09376" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF"/> 
     <Rectangle Width="6.71874" Height="31.8437" Canvas.Left="25.2812" Canvas.Top="0.250002" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF"/> 
    </Canvas> 
</ControlTemplate> 

<ControlTemplate x:Key="Signal2"> 
    <Canvas Width="32" Height="32" Canvas.Left="0" Canvas.Top="0"> 
     <Rectangle Width="5.4375" Height="11.375" Canvas.Left="0.0937499" Canvas.Top="20.6563" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF37F307"/> 
     <Rectangle Width="6.40625" Height="16" Canvas.Left="5.34375" Canvas.Top="16.0313" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF37F307"/> 
     <Path Width="6.88835" Height="21.6562" Canvas.Left="11.75" Canvas.Top="10.375" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF" Data="F1 M 12.2768,10.875L 18.1384,10.875L 18.1115,31.5313L 12.25,31.5313L 12.2768,10.875 Z "/> 
     <Rectangle Width="6.78126" Height="26.9687" Canvas.Left="18.5625" Canvas.Top="5.09376" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF"/> 
     <Rectangle Width="6.71874" Height="31.8437" Canvas.Left="25.2812" Canvas.Top="0.250002" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF"/> 
    </Canvas> 
</ControlTemplate> 

現在我需要返回此從我的控制模板查看模型將其綁定到一個按鈕,以在我的列表框中顯示適當的信號強度。

我可能需要從信號強度(int)到控制模板的某種轉換。

任何建議/代碼示例來實現這個任務?

+0

鑑於您的視圖**模型**不應該瞭解WPF,所以您的設計有更大的問題。 – 2011-05-09 20:43:19

回答

1

這應該引導到正確的方向:

<ItemsControl ItemsSource="{Binding AvailableNetworks }"> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Rectangle Width="20" Height="{Binding SignalStrength,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
        Fill="{Binding Color,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></Rectangle> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 
1

我喜歡Darek的答案,但如果你真的想使用控件模板這樣,你應該使用樣式和數據觸發綁定到的信號強度,例如:

<Style TargetType="{x:Type MyControl}"> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding SignalStrength}" Value="1"> 
      <Setter Property="ControlTemplate" Value="{StaticResource Signal1}"/> 
     </DataTrigger> 
     <DataTrigger Binding="{Binding SignalStrength}" Value="2"> 
      <Setter Property="ControlTemplate" Value="{StaticResource Signal2}"/> 
     </DataTrigger> 
     <!-- and so on --> 
    </Style.Triggers> 
</Style> 
0

另一種方法是在列表框中使用ItemTemplate並創建一個轉換器類。

創建一個名爲ColorConverter公共類,並使用在它下面的代碼:與列表框的頁面上

public class ColorConverter : IValueConverter 
{ 
    #region Implementation of IValueConverter 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     try 
     { 
      var val = System.Convert.ToInt32(value.ToString()); 
      var param = System.Convert.ToInt32(parameter.ToString()); 

      return val >= param ? Brushes.Green : Brushes.White; 

     } 
     catch 
     { 
      return Brushes.White; 
     } 
    } 

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

    #endregion 
} 

然後分配轉換器:

<Window.Resources> 
    <Converters:ColorConverter x:Key="colorConverter" /> 
</Window.Resources> 

確保你把命名空間xaml頂部的「轉換器」:

xmlns:Converters="clr-namespace:ProjectNameHere" 

然後創建一個DataTemp後期在你列表框使用以上代碼,替換綁定到正確的形式:

<ListBox Margin="0,73,0,0" ItemsSource="{Binding AvailableNetworks}"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <Canvas Width="32" 
         Height="32" 
         Canvas.Left="0" 
         Canvas.Top="0"> 
        <Rectangle Width="5.4375" 
           Height="11.375" 
           Canvas.Left="0.0937499" 
           Canvas.Top="20.6563" 
           Stretch="Fill" 
           StrokeLineJoin="Round" 
           Stroke="#FF000000" 
           Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=0}" /> 
        <Rectangle Width="6.40625" 
           Height="16" 
           Canvas.Left="5.34375" 
           Canvas.Top="16.0313" 
           Stretch="Fill" 
           StrokeLineJoin="Round" 
           Stroke="#FF000000" 
           Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=20}" /> 
        <Path Width="6.88835" 
          Height="21.6562" 
          Canvas.Left="11.75" 
          Canvas.Top="10.375" 
          Stretch="Fill" 
          StrokeLineJoin="Round" 
          Stroke="#FF000000" 
          Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=40}" 
          Data="F1 M 12.2768,10.875L 18.1384,10.875L 18.1115,31.5313L 12.25,31.5313L 12.2768,10.875 Z " /> 
        <Rectangle Width="6.78126" 
           Height="26.9687" 
           Canvas.Left="18.5625" 
           Canvas.Top="5.09376" 
           Stretch="Fill" 
           StrokeLineJoin="Round" 
           Stroke="#FF000000" 
           Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=60}" /> 
        <Rectangle Width="6.71874" 
           Height="31.8437" 
           Canvas.Left="25.2812" 
           Canvas.Top="0.250002" 
           Stretch="Fill" 
           StrokeLineJoin="Round" 
           Stroke="#FF000000" 
           Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=80}" /> 
       </Canvas> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 

向下的一面,以做這種方式是缺乏風格重用的,不像提到的其他方法。