我有绑定到不同类别的 ViewModel 类的不同控件组。
视图模型是
-
MainViewModel
-
VideoViewModel
-
AudioViewModel
问题
如何使用 XAML 而不是 C# 设置DataContext
?
1.我尝试将DataContext="{Binding VideoViewModel}"
添加到ComboBox
XAML,但它不起作用,并且项目为空。
2.我还尝试将UserControl
内某个类别的所有ComboBoxes
与DataContext
分组:
<UserControl DataContext="{Binding VideoViewModel}">
<!-- ComboBoxes in here -->
</UserControl>
3.还尝试将<Window>
DataContext
设置为自身DataContext="{Binding RelativeSource={RelativeSource Self}}"
数据上下文
我目前正在为不同类别的控件设置这种DataContext
:
public MainWindow()
{
InitializeComponent();
// Main
this.DataContext =
tbxInput.DataContext =
tbxOutput.DataContext =
cboPreset.DataContext =
MainViewModel.vm;
// Video
cboVideo_Codec.DataContext =
cboVideo_Quality.DataContext =
tbxVideo_BitRate.DataContext =
cboVideo_Scale.DataContext =
VideoViewModel.vm;
// Audio
cboAudio_Codec.DataContext =
cboAudio_Quality.DataContext =
tbxAudio_BitRate.DataContext =
tbxAudio_Volume.DataContext =
AudioViewModel.vm;
}
XAML 组合框
<ComboBox x:Name="cboVideo_Quality"
DataContext="{Binding VideoViewModel}"
ItemsSource="{Binding Video_Quality_Items}"
SelectedItem="{Binding Video_Quality_SelectedItem}"
IsEnabled="{Binding Video_Quality_IsEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="105"
Height="22"
Margin="0,0,0,0"/>
视频视图模型类
public class VideoViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private void OnPropertyChanged(string prop)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(prop));
}
}
public VideoViewModel() { }
public static VideoViewModel _vm = new VideoViewModel();
public static VideoViewModel vm
{
get { return _vm; }
set
{
_vm = value;
}
}
// Items Source
private List<string> _Video_Quality_Items = new List<string>()
{
"High",
"Medium",
"Low",
};
public List<string> Video_Quality_Items
{
get { return _Video_Quality_Items; }
set
{
_Video_Quality_Items = value;
OnPropertyChanged("Video_Quality_Items");
}
}
// Selected Item
private string _Video_Quality_SelectedItem { get; set; }
public string Video_Quality_SelectedItem
{
get { return _Video_Quality_SelectedItem; }
set
{
if (_Video_Quality_SelectedItem == value)
{
return;
}
_Video_Quality_SelectedItem = value;
OnPropertyChanged("Video_Quality_SelectedItem");
}
}
// Enabled
private bool _Video_Quality_IsEnabled;
public bool Video_Quality_IsEnabled
{
get { return _Video_Quality_IsEnabled; }
set
{
if (_Video_Quality_IsEnabled == value)
{
return;
}
_Video_Quality_IsEnabled = value;
OnPropertyChanged("Video_Quality_IsEnabled");
}
}
}
您可以在 xaml 中实例化对象:
<Window.DataContext>
<local:MainWindowViewmodel/>
</Window.DataContext>
您也可以为用户控件视图模型执行此操作。
更常见的情况是,任何子视图模型都在窗口视图模型中实例化。公开为公共属性和子视图模型的数据上下文,然后绑定到该属性。
我建议你先谷歌视图模型,看看一些样本。
我不确定这是否是正确的方法,但我能够将ComboBoxes
组绑定到不同的 ViewModels。
我创建了一个视图模型来引用它们。
public class VM: INotifyPropertyChanged
{
...
public static MainViewModel MainView { get; set; } = new MainViewModel ();
public static VideoViewModel VideoView { get; set; } = new VideoViewModel ();
public static AudioViewModel AudioView { get; set; } = new AudioViewModel ();
}
我在MainWindow.xaml
中使用了安迪的建议<local:VM>
。
<Window x:Class="MyProgram.MainWindow"
...
xmlns:local="clr-namespace:MyProgram"
>
<Window.DataContext>
<local:VM/>
</Window.DataContext>
并用了DataContext
设置为VideoView
的UserControl
,里面有ComboBoxes
。
代替UserControl
,也可以只在每个绑定上使用VideoView.Your_Property_Name
。
<UserControl DataContext="{Binding VideoView}">
<StackPanel>
<ComboBox x:Name="cboVideo_Quality"
ItemsSource="{Binding Video_Quality_Items}"
SelectedItem="{Binding Video_Quality_SelectedItem}"
IsEnabled="{Binding Video_Quality_IsEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="105"
Height="22"
Margin="0,0,0,0"/>
<!-- Other ComboBoxes with DataContext VideoView in here -->
</StackPanel>
</UserControl>
然后访问其中一个属性:
VM.VideoView.Video_Codec_SelectedItem = "x264";
VM.VideoView.Video_Quality_SelectedItem = "High";
VM.AudioView.Audio_Codec_SelectedItem = "AAC";
VM.AudioView.Audio_Quality_SelectedItem = "320k";
其他人显然提供了很好的答案,但是,绑定的潜在缺失是主视图模型的第一组 DataContext = = = = = 。
一旦将主窗体的数据上下文连接到主视图模型,其下的每个控件都期望 ITS START 点作为主视图模型。 由于主视图模型在视频和音频视图模型的 IT 下没有公共属性,因此找不到要绑定的它们。
如果删除"这个。DataContext =",则没有默认的数据上下文,每个控件都应该能够按照您的预期进行绑定。
所以改变
this.DataContext =
tbxInput.DataContext =
tbxOutput.DataContext =
cboPreset.DataContext =
MainViewModel.vm;
自
tbxInput.DataContext =
tbxOutput.DataContext =
cboPreset.DataContext =
MainViewModel.vm;