所以我有一个包含TabControl的页面,它使用多个UserControls(每个用户控件代表一个TabItem的内容)。
我在两个共享相同ItemsSource(OrganizationSource
)和SelectedValue(OrganizationSelected
)属性的用户控件中都有一个ComboBox,
但是我似乎无法绑定到EventDetails
UserControl中的ComboBox,但它在OrganizationDetails
UserControl中完美无缺地工作。
OutreachMVVM
设置为选项卡所在父页面的DataContext。我仍然需要为用户控件本身设置datacontexts才能使其正常工作。
我只需要弄清楚如何在EventDetails
内设置ComboBox的绑定。我看到了一些关于依赖属性的东西,但我不明白。我以为我能够将EventDetails
内的ComboBox的绑定设置为OrganizationDetails
内的ComboBox的绑定,但事实并非如此。
internal class OutreachMVVM : ViewModelBase
{
public OutreachMVVM()
{
EventDetails = new EventDetailsVMB();
OrganizationDetails = new OrganizationDetailsVMB();
}
public EventDetailsVMB EventDetails { get; set; }
public OrganizationDetailsVMB OrganizationDetails { get; set; }
}
EventDetailsVMB:
class EventDetailsVMB : ViewModelBase
{
private string _eventTypeSelected;
private string _zipSelected;
private readonly UserListTableAdapter _userListTableAdapter = new UserListTableAdapter();
private readonly EventTypeListTableAdapter _eventTypeListTableAdapter = new EventTypeListTableAdapter();
private readonly CityListTableAdapter _cityListTableAdapter = new CityListTableAdapter();
private readonly LocationInfoByZipTableAdapter _locationInfoByZipTableAdapter = new LocationInfoByZipTableAdapter();
public string User { get; set; }
public string EventName { get; set; }
public string Location { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string County { get; set; }
public string ServiceArea { get; set; }
//Set EventType CombBox
public ObservableCollection<string> EventTypeSource
{
get
{
var eventTypeList = _eventTypeListTableAdapter.GetEventTypeList();
var eventTypeSource = new ObservableCollection<string>();
eventTypeSource.AddRange(from DataRow row in eventTypeList.Rows select row.ItemArray[0].ToString());
return eventTypeSource;
}
}
//Set User ComboBox
public ObservableCollection<string> UserSource
{
get
{
var userList = _userListTableAdapter.GetUserList();
var userSource = new ObservableCollection<string>();
foreach (var username in Enumerable.Where(userList, username => username.Username == Environment.UserName))
{
User = username.FullName;
}
userSource.AddRange(from DataRow row in userList.Rows select row.ItemArray[0].ToString());
OnPropertyChanged("User");
return userSource;
}
}
//Set City RadAutoCompleteBox
public ObservableCollection<string> CitySource
{
get
{
var cityList = _cityListTableAdapter.GetCityList();
var citySource = new ObservableCollection<string>();
citySource.AddRange(from DataRow row in cityList.Rows select row.ItemArray[0].ToString());
return citySource;
}
}
public string EventTypeSelected
{
get { return _eventTypeSelected; }
set
{
_eventTypeSelected = value;
OnPropertyChanged("EventTypeSelected");
}
}
public string ZipSelected
{
get { return _zipSelected; }
set
{
_zipSelected = value;
var locationInfo = _locationInfoByZipTableAdapter.GetLocationInfoByZip(_zipSelected);
if (locationInfo.Rows.Count != 0)
{
City = locationInfo.Rows[0].ItemArray[0].ToString();
State = locationInfo.Rows[0].ItemArray[1].ToString();
County = locationInfo.Rows[0].ItemArray[2].ToString();
ServiceArea = locationInfo.Rows[0].ItemArray[3].ToString();
}
else if (ZipSelected.Length == 5) {}
else
{
City = "";
State = "TX";
County = null;
ServiceArea = null;
}
OnPropertyChanged("City");
OnPropertyChanged("State");
OnPropertyChanged("County");
OnPropertyChanged("ServiceArea");
}
}
}
OrganizationDetailsVMB:
class OrganizationDetailsVMB : ViewModelBase
{
private string _organizationName;
private string _street1;
private string _street2;
private string _city;
private string _state;
private string _zip;
private string _county;
private string _serviceArea;
private bool _cbo;
private bool _fbo;
private bool _mo;
private bool _sbo;
private bool _sno;
private readonly OrganizationListTableAdapter _organizationListTableAdapter = new OrganizationListTableAdapter();
private readonly OrgByNameTableAdapter _orgByNameTableAdapter = new OrgByNameTableAdapter();
private readonly OrgTypeByOrgNameTableAdapter _orgTypeByOrgNameTableAdapter = new OrgTypeByOrgNameTableAdapter();
public string OrganizationSelected
{
get { return _organizationName; }
set
{
_organizationName = value;
var organizationQueryResults = _orgByNameTableAdapter.GetOrganizationByName(_organizationName);
var orgTypeQueryResults = _orgTypeByOrgNameTableAdapter.GetOrgTypeByName(_organizationName);
if (organizationQueryResults.Rows.Count != 0)
{
OrgStreet1Value = organizationQueryResults.Rows[0].ItemArray[1].ToString();
OrgStreet2Value = organizationQueryResults.Rows[0].ItemArray[2].ToString();
OrgCityValue = organizationQueryResults.Rows[0].ItemArray[3].ToString();
OrgStateValue = organizationQueryResults.Rows[0].ItemArray[4].ToString();
OrgZipValue = organizationQueryResults.Rows[0].ItemArray[5].ToString();
OrgCountyValue = organizationQueryResults.Rows[0].ItemArray[6].ToString();
OrgServiceAreaValue = organizationQueryResults.Rows[0].ItemArray[7].ToString();
CBO = Convert.ToBoolean(orgTypeQueryResults.Rows[0].ItemArray[1]);
FBO = Convert.ToBoolean(orgTypeQueryResults.Rows[0].ItemArray[2]);
SBO = Convert.ToBoolean(orgTypeQueryResults.Rows[0].ItemArray[3]);
MO = Convert.ToBoolean(orgTypeQueryResults.Rows[0].ItemArray[4]);
SNO = Convert.ToBoolean(orgTypeQueryResults.Rows[0].ItemArray[5]);
}
else
{
OrgStreet1Value = "";
OrgStreet2Value = "";
OrgCityValue = "";
OrgStateValue = "";
OrgZipValue = "";
OrgCountyValue = "";
OrgServiceAreaValue = "";
CBO = false;
FBO = false;
SBO = false;
MO = false;
SNO = false;
}
}
}
public ObservableCollection<string> OrganizationSource
{
get
{
var organizationList = _organizationListTableAdapter.GetOrganizationList();
var organizationSource = new ObservableCollection<string>();
organizationSource.AddRange(from DataRow row in organizationList.Rows select row.ItemArray[0].ToString());
return organizationSource;
}
}
public string OrgStreet1Value
{
get { return _street1; }
set
{
if (_street1 != value)
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "OrgStreet1Value" });
_street1 = value;
OnPropertyChanged("OrgStreet1Value");
}
}
}
public string OrgStreet2Value
{
get { return _street2; }
set
{
if (_street2 != value)
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "OrgStreet2Value" });
_street2 = value;
OnPropertyChanged("OrgStreet2Value");
}
}
}
public string OrgCityValue
{
get { return _city; }
set
{
if (_street1 != value)
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "OrgCityValue" });
_city = value;
OnPropertyChanged("OrgCityValue");
}
}
}
public string OrgStateValue
{
get { return _state; }
set
{
if (_state != value)
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "OrgStateValue" });
_state = value;
OnPropertyChanged("OrgStateValue");
}
}
}
public string OrgZipValue
{
get { return _zip; }
set
{
if (_zip != value)
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "OrgZipValue" });
_zip = value;
OnPropertyChanged("OrgZipValue");
}
}
}
public string OrgCountyValue
{
get { return _county; }
set
{
if (_county != value)
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "OrgCountyValue" });
_county = value;
OnPropertyChanged("OrgCountyValue");
}
}
}
public string OrgServiceAreaValue
{
get { return _serviceArea; }
set
{
if (_serviceArea != value)
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "OrgServiceAreaValue" });
_serviceArea = value;
OnPropertyChanged("OrgServiceAreaValue");
}
}
}
public bool CBO
{
get { return _cbo; }
set
{
_cbo = value;
OnPropertyChanged("CBO");
}
}
public bool FBO
{
get { return _fbo; }
set
{
_fbo = value;
OnPropertyChanged("FBO");
}
}
public bool SBO
{
get { return _sbo; }
set
{
_sbo = value;
OnPropertyChanged("SBO");
}
}
public bool MO
{
get { return _mo; }
set
{
_mo = value;
OnPropertyChanged("MO");
}
}
public bool SNO
{
get { return _sno; }
set
{
_sno = value;
OnPropertyChanged("SNO");
}
}
}
EventDetailsTab:
<TabItem Header="Event Details" x:Name="EventDetailsTab"
Style="{StaticResource TabStyle}"
DataContext="{Binding EventDetails}">
<eventTabs:_1_EventDetailsTab />
</TabItem>
OrganizationDetailsTab:
<TabItem Header="Organization" x:Name="OrganizationTab"
Style="{StaticResource TabStyle}"
DataContext="{Binding OrganizationDetails}">
<eventTabs:_2_OrganizationTab />
</TabItem>
正如我所说,绑定整体上完美无缺,但是我想引用与OrganizationDetails相关联的绑定,以获取驻留在EventDetailsTab和OrganizationDetailsTab中的控件。
该项目的代码如下......
<ComboBox Name="OrgNameComboBox" ItemsSource="{Binding OrganizationSource}"
SelectedValue="{Binding OrganizationSelected,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
答案 0 :(得分:1)
您要将事件详细信息选项卡的DataContext设置为{Binding EventDetails}
,将组织选项卡的DataContext设置为{Binding OrganizationDetails}
,但将OrganizationSource
和OrganizationSelected
字段设置为<ComboBox Name="OrgNameComboBox" ItemsSource="{Binding OrganizationSource}"
DataContext="{Binding RelativeSource={RelativeSource AncestorType=TabControl}, Path=DataContext.OrganizationDetails}"
SelectedValue="{Binding OrganizationSelected,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
ComboBox绑定仅存在于OrganizationDetailsVMB类中。快速入侵是将您的事件详细信息更改为ComboBox以指向正确的位置,其中RelativeSource绑定回TabItem的DataContext,然后再次返回到OrganizationDetails:
Users = Array ( [0] => 1 [1] => 1 [2] => 1 )
Types = Array ( [0] => 0 [1] => 1 [2] => 0 )
虽然我认为你需要清理你的架构,但要说实话。您的视图模型与您的基础数据模型非常紧密地耦合,而不是视图,甚至是您在getter中访问表适配器的位置,这意味着A)您无法进行会话管理,B)您的视图性能现在将被你的DAL限制,你将开始遇到性能问题,而C)试图引入任何类型的多线程将导致你的ORM中出现各种访问冲突。
答案 1 :(得分:0)
如果您希望在App
或Multi Window
中包含一些数据(例如组合框信息),这种方式很好:
创建3 ViewModel
(全部继承自INotifyPropertyChanged
)。
OrganizationViewModel
:包含 OrganizationSource
和 OrganizationSelected
< / LI>
OrganizationDetailsViewModel
: WHITHOUT OrganizationSource
和 OrganizationSelected
< / LI>
OrganizationEventsViewModel
: WHITHOUT OrganizationSource
和 OrganizationSelected
< / LI>
醇>
现在,您可以创建一个名为Static
&amp;的简单GeneralData
类。在static
类型中创建一个OrganizationViewModel
属性,如下所示:
public static class GeneralData{
public static OrganizationViewModel Organization {get;set;}
}
在App.xaml.cs
中填充Organization
类的GeneralData
属性,其中包含OrganizationViewModel
的新实例。
好的......现在我们有了开始玩的所有东西......
每次要填充ComboBox
时,都应该使用Organization
类的GeneralData
[静态属性],如下所示:
<ComboBox Name="OrgNameComboBox"
DataSource="{Binding Source={x:Static GeneralData.Organization}}"
ItemsSource="{Binding Source={x:Static GeneralData.Organization.OrganizationSource}}"
SelectedValue="{Binding Source={x:Static GeneralData.Organization.OrganizationSelected,
Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
每次你想检查在代码隐藏中选择哪个Combobox项目(例如在ViewModels
内),你可以像这样轻松检查:
var selectedOrganisation = GeneralData.Organization.OrganizationSelected;
注意:在关闭包含ComboBox的窗口之前,我建议您运行此代码(以确保没有对static属性的任何活动引用):
BindingOperations.ClearAllBindings(OrgNameComboBox);
如果您只有1个窗口包含2个UserControl,则阻止static
属性,而不是以上方式使用此方式:
创建3 ViewModel
(全部继承自INotifyPropertyChanged
)。
OrganizationViewModel
:包含 OrganizationSource
和 OrganizationSelected
< / LI>
OrganizationDetailsViewModel
: WHITHOUT OrganizationSource
和 OrganizationSelected
< / LI>
OrganizationEventsViewModel
: WHITHOUT OrganizationSource
和 OrganizationSelected
< / LI>
醇>
现在可以轻松实现此方案:
在Window1.xaml.cs
:
Window1.DataSource= new OrganizationViewModel();
在EventUserControl.xaml.cs
:
EventUserControl.DataSource= new OrganizationEventsViewModel();
在OrganizationDetailsUserControl.xaml.cs
:
EventUserControl.DataSource= new OrganizationDetailsViewModel();
现在在DependencyProperty
和EventUserControl
中创建OrganizationDetailsUserControl
,为其提供SelectedItem
ComboBox
。您的房产类型应为string
。您可以在this tutorial上创建DependencyProperty
个基础。
例如,在DependencyProperty
的{{1}}中UserControl
使用此名称: SelectedOrganisation
好的,将Combobox
放入Window1.xaml
(不在任何UserControl
内)。
现在,我们从SelectedOrganisation
外部填充这些UserControls
,如下面的代码。
在Window1.xaml
<uc.OrganizationDetailsUserControl
SelectedOrganisation="{Binding ElementName=OrgNameComboBox, Path=SelectedItem}"/>
<uc.EventUserControl
SelectedOrganisation="{Binding ElementName=OrgNameComboBox, Path=SelectedItem}"/>
现在,您SelectedItem
内的ComboBox
UserControl
可以在UserControls
内使用ViewModels
,并调用SelectedOrganisation
的某些方法guard-minitest
作为方法参数。
答案 2 :(得分:0)
我采取的路线是MVVM Light Toolkit。