2011-05-09 118 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> 

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