找到了这么多示例,但没有一个适合!我的列表框是Result对象的列表。可以在列表框中选中或取消选中结果,将其标记为"允许"传输。
<ListBox
x:Name="FileListBox"
ItemsSource="{Binding TestResults}"
ItemTemplate="{StaticResource FileListTemplate}"
SelectionMode="Single"
SelectedItem="{Binding FileListSelected}"
Background="#FFFFFBE2" />
FileListTemplate
<DataTemplate x:Key="FileListTemplate">
<Grid HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*" />
<ColumnDefinition Width=".3*" />
<ColumnDefinition Width=".2*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="{Binding FileName}" />
<TextBlock Grid.Column="1"
Text="Machine">
</TextBlock>
<CheckBox x:Name="UploadOK"
Grid.Column="2"
HorizontalAlignment="Right"
IsChecked="{Binding CanUpload, Mode=TwoWay}" />
</Grid>
</DataTemplate>
我拿出了很多格式化代码来减少混乱。因此,当复选框被选中(或未选中)时,我需要将对象上的布尔值设置为true或false。但我不希望仅仅因为选中了复选框就选中ListItem。当ListItem被选中时,会发生其他事情。这是它的代码。
public TestResult FileListSelected
{
get
{
return selectedItem;
}
set
{
if (value == selectedItem)
return;
selectedItem = value;
if (!Workspaces.Any(p => p.DisplayName == value.FileName))
{
this.DisplayTestResult(value as TestResult);
}
base.RaisePropertyChanged("FileListSelected");
}
}
这是我为复选框绑定的代码(尽管它不起作用)。
public bool CanUpload
{
get { return selectedItem.CanUpload; }
set
{
selectedItem.CanUpload = value;
}
}
我很感激你看到这个。
Internal Class TestResult
{
...
private bool _canUpload;
public bool CanUpload
{
get { return _canUpload; }
set
{
_canUpload = value;
base.RaisePropertyChanged("CanUpload");
}
}
}
使用MVVM
时,请始终检查以下各项:
- 将
using System.ComponentModel;
添加到ViewModelClass - 从
INotifyPropertyChanged
继承 - 始终检查DataContext并查看
BindingErrors
的Output
窗口 - 创建这样的绑定:
示例属性:
public string Example
{
get { return _example; }
set
{
_example= value;
OnPropertyChanged();
}
}
每当分配新值时,这将自动调用OnPropertyChanged
(从其他位置更改后不会自动更新!)
确保INotifyPropertyChanged
的实现如下所示:
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
为此,您还需要using System.Runtime.CompilerServices;
让你的代码工作的其他选项:
- 你的
TestResults
应该是ObservableCollection<TestResult>
- TestResult应具有
CanUpload
和FileName
的属性,并从INotifyPropertyChanged
继承
然后在MainViewModel上,例如在和ButtonClick上,您可以获得如下所选的文件:
private List<string> GetSelectedFiles()
{
return TestResults.Where(result => result.CanUpload == true).Select(r => r.FileName).ToList());
}
注意:
FileListSelected
是ListBox
的DataContext的一个属性,它不同于条目的DataContext
(或者至少应该是)。
FileListSelected
将返回您的ItemsSource
的选定项目。
也许你可以通过行选择/复选框检查来评论这个问题,并添加一些细节,这样我可以为你提供更多帮助。
编辑:将复选框状态更改通知MainWindowViewModel:
我在这里看到了两种可能的方法:
使用事件
将其添加到您的TestResult
类:
public delegate void CheckBoxStateChangedHandler(object sender, CheckBoxStateChangedEventArgs e);
public event CheckBoxStateChangedHandler CheckBoxStateChanged;
public class CheckBoxStateChangedEventArgs
{
bool CheckBoxChecked { get; set; }
}
确保在您的MainViewModel
中创建新的TestResult
时,您订阅了该event
;
testResult.CheckBoxStateChanged += CheckBox_StateChanged;
在CheckBox_StateChanged
中更改状态后,处理您想要执行的操作。注意,参数e
包含布尔值(选中)和作为发送方的相应TestResult
。
您只需在CheckBox.Checked Binding
:的Setter中调用您的新事件
public bool Checked
{
get { return _checked; }
set
{
_checked = value;
OnPropertyChanged();
CheckBoxStateChanged.Invoke(this, new CheckBoxStateChangedEventArgs() { CheckBoxChecked = value })
}
}
调用MAINWINDOWVIEWMODEL方法
为此,您需要创建MainWindowViewModel
的static
对象(在MainViewModel中)-创建MainWindowViewModel
后不要忘记指定值。
public static MainViewModel Instance { get; set; }
然后根据需要简单地添加一个公共方法:
public void CheckBoxValueChanged(bool value, TestResult result)
{
//Do whatever
}
您也可以在调用上面的事件时从同一位置调用。
public bool Checked
{
get { return _checked; }
set
{
_checked = value;
OnPropertyChanged();
MainWindowViewModel.Instance.CheckBoxValueChanged(value, this);
}
}