我有绑定到不同类别ViewModel类的不同控件组。
ViewModel是
MainViewModel
VideoViewModel
AudioViewModel
问题
如何使用XAML而不是C#设置DataContext
?
1。。我尝试将DataContext="{Binding VideoViewModel}"
添加到ComboBox
XAML中,但是它不起作用,并且项目显示为空。
2。。我还尝试将ComboBoxes
中某个类别的所有UserControl
与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;
}
<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");
}
}
}
答案 0 :(得分:0)
您可以在xaml中实例化一个对象:
<Window.DataContext>
<local:MainWindowViewmodel/>
</Window.DataContext>
您也可以对用户控件的视图模型进行操作。
在窗口视图模型中实例化任何子视图模型更为常见。作为公共属性公开,然后将子视图模型的数据上下文绑定到该属性。
我建议您首先使用google viewmodel,然后看一些示例。
答案 1 :(得分:0)
我不确定这是否正确,但是我能够将ComboBoxes
组绑定到不同的ViewModels。
我创建了一个ViewModel来引用它们。
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 ();
}
我在<local:VM>
中使用了安迪的建议MainWindow.xaml
。
<Window x:Class="MyProgram.MainWindow"
...
xmlns:local="clr-namespace:MyProgram"
>
<Window.DataContext>
<local:VM/>
</Window.DataContext>
并使用一个UserControl
,其中DataContext
设置为VideoView
,且内部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";
答案 2 :(得分:0)
其他人显然提供了很好的答案,但是,绑定的根本问题是您对主视图模型的第一套DataContext = = = = =。
一旦您将主窗体的数据上下文连接到MAIN视图模型,则其下的每个控件都将ITS STARTING点作为MAIN视图模型。由于MAIN视图模型在视频和音频视图模型的基础上没有公共财产,因此它找不到绑定的对象。
如果删除“ this.DataContext =”,则将没有默认的数据上下文,并且每个控件都应该能够按预期的方式进行绑定。
所以改变
this.DataContext =
tbxInput.DataContext =
tbxOutput.DataContext =
cboPreset.DataContext =
MainViewModel.vm;
到
tbxInput.DataContext =
tbxOutput.DataContext =
cboPreset.DataContext =
MainViewModel.vm;