【问题标题】:WPF MVVM: Returning selected ListBox item on User Control back to ViewModelWPF MVVM:将用户控件上的选定列表框项返回给 ViewModel
【发布时间】:2019-12-10 23:29:24
【问题描述】:

我在带有“选择”按钮的用户控件上显示了一个设备列表。列表数据来自父 ViewModel,我希望用户选择他们想要的设备,点击“选择”按钮,按钮命令返回所选设备。

此外,我想要一个单选按钮或矩形来更改颜色以表示并与活动选择同步工作(即,您可以选择单选按钮并选择 ListItem 或单击 ListItem 并获得单选按钮选择)。

我有绑定到 ListBox 的工作,所以它显示设备,但我不知道如何让绑定工作,所以选择返回。

这是我正在使用的:

查看模型

// Props
private MutlipleAttachedDevicesModel _selectedDevice;
public MutlipleAttachedDevicesModel SelectedDevice
{
   get { return _selectedDevice; }
   set
   {
      _selectedDevice = value;
      RaisePropertyChanged();
   }
}

// Methods
public void DisplaySelectDevices()
{
    // Create new display
    DeviceSelectionVM = new DeviceSelectionViewModel();
    CurrentView = DeviceSelectionVM;

    // Populate Device List
    DeviceList = PopulateDeviceList();

}

private void CreateDummyData()
{
    Random r = new Random();
    var count = 0;   

    // make a max of 3 devices
    for(var i = 0; i < 3; i++)
    {
       DeviceList.Add(new MutlipleAttachedDevicesModel()
       {
           Name = "SP-2 Super Processor",
           Serial = $"SP2-00"+ r.Next(100).ToString(),
           IsSelection = false,
           WasUpdated = false
       });

       // First Device defaults to selected
       if (i == 0)
           DeviceList[i].IsSelection = true;

       count++;
    }
}

private void SelectTargetDevice(object selection)
{
    // Display Target Device
    var count = DeviceList.Count;

    for (var i=0; i<=count; i++)
    {
        if (DeviceList[i].IsSelection == true)
        {
            SelectedDevice = DeviceList[i];
            break;
        }        
    }

    Trace.WriteLine("Selection was "+ SelectedDevice.Serial);
}

列表框

<ListBox x:Name="MultipleDeviceSelectionList"
    ItemsSource="{Binding DataContext.DeviceList, 
                  RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Page}}"
    SelectedItem="{Binding IsSelection, 
                   RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Page}, 
                   Mode=TwoWay}">
   <ListBox.ItemTemplate>
      <DataTemplate>
         <Grid>
           <Grid.RowDefinitions>
           <Grid.ColumnDefinitions>

           <RadioButton  GroupName="radio"  
                         IsChecked="{Binding IsSelection}" />

           <TextBlock Text="{Binding Name}"/>

           <StackPanel>
              <TextBlock>
                 Serial #: 
              </TextBlock>
              <TextBlock Text="{Binding Serial}"/>
           </StackPanel>

           <TextBlock Visibility="{Binding WasUpdated, 
                                   Converter={StaticResource BoolToVisConverter}, 
                                   FallbackValue=Hidden}">
              Up To Date
           </TextBlock>
        </Grid>
     </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

<Button Command="{Binding DataContext.SelectButtonCommand, 
                  RelativeSource={RelativeSource Mode=FindAncestor,
                  AncestorType=Page}}">
   Select
</Button>

我还尝试了其他方法,例如尝试将单选按钮双向绑定到 ListBox 的 SelectedItem 属性,但老实说,复杂的绑定仍然让我感到困惑。我需要做什么才能使单选按钮与列表选择保持同步,并正确返回列表选择?

【问题讨论】:

  • 为什么不直接将SelectedDevice绑定到列表框的SelectedItem属性上呢?
  • IsSelection 是 bool 类型,但您将其绑定到 Device 类型的 SelectedItem。将其绑定到选定的设备。
  • 什么是IsSelection,为什么要绑定它?
  • 起初,我没有意识到 ListBox 有一个选择机制,所以我使用IsSelection 在列表上设置默认选择,这就是我计划如何确定用户选择的内容。
  • @AthulRaj, Sorush:看,我什至没有意识到你可以做到这一点。我陷入了绑定单个属性(例如“名称”)的心态,很难实现这一飞跃,并且理解绑定可以将选定模型设置为 SelectedDevice。

标签: c# wpf mvvm data-binding


【解决方案1】:

更改您的 ListView SelectedItem 绑定。 您想绑定到 SelectedDevice 属性。

<ListBox x:Name="MultipleDeviceSelectionList"
    ItemsSource="{Binding DataContext.DeviceList, 
                  RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Page}}"
    SelectedItem="{Binding SelectedDevice, 
                   RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Page}, 
                   Mode=TwoWay}">

但也许您真的应该检查属性是否属于正确的类型,因为“MutlipleAttachedDevicesModel”看起来不像单个设备的模型。另外我不确定您是否需要该绑定上的 RelativeSource。

【讨论】:

  • Fabian P:谢谢,这行得通!那么如何让单选按钮或矩形与列表选择同步呢?我需要将这些属性绑定到什么? ListBox 的SelectedItem 属性?
  • 另外,“MultipleAttachedDevicesModel”是正确的,这是我为此目的创建的模型,只有我需要的参数。实际上,我已经将这一切都更改为“设备模型”,因为我实际上需要所有这些信息来保持应用程序的生命周期。
  • 没关系,我明白了。我只是将单选按钮绑定更改为:&lt;RadioButton IsChecked="{Binding IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}}"/&gt;!
猜你喜欢
  • 1970-01-01
  • 2013-11-15
  • 2016-08-29
  • 2011-10-16
  • 2013-07-04
  • 1970-01-01
  • 1970-01-01
  • 2011-06-28
  • 2018-10-14
相关资源
最近更新 更多