设置窗口

This commit is contained in:
lxmou666 2020-12-24 02:23:11 +08:00
parent 4c0b1962fe
commit de4c763f06
19 changed files with 1219 additions and 36 deletions

View File

@ -12,6 +12,7 @@
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/JianGongYun;component/Style/ShowControl.xaml"/>
<ResourceDictionary Source="pack://application:,,,/JianGongYun;component/Style/TRTCResource.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>

View File

@ -15,6 +15,8 @@
<PackageReference Include="AduSkin" Version="1.1.1.8" />
<PackageReference Include="CommonServiceLocator" Version="2.0.5" />
<PackageReference Include="MvvmLightLibs" Version="5.4.1.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="zlib.net" Version="1.0.4" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'net45'">
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.0" />

View File

@ -0,0 +1,100 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Metro="clr-namespace:AduSkin.Controls.Metro;assembly=AduSkin">
<!--#region 设置窗口布局样式-->
<SolidColorBrush x:Key="DefaultBorderBrush" Color="#424346" />
<SolidColorBrush x:Key="ComboBoxBrush" Color="#6a6a6a"></SolidColorBrush>
<SolidColorBrush x:Key="Item.SelectedActive.foreground" Color="#396cd2" />
<SolidColorBrush x:Key="Item.MouseOver.Border" Color="#a826A0Da" />
<Style x:Key="LeftIndicatorStyle" TargetType="{x:Type Metro:SegmentControl}">
<Setter Property="Padding" Value="0" />
<Setter Property="CornerRadius" Value="0" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="BorderThickness" Value="0,0,0,0" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="Background" Value="#2a2b30" />
<Setter Property="Foreground" Value="#ffffff" />
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" IsItemsHost="True" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="LeftIndicatorItemStyle" TargetType="{x:Type Metro:SegmentItem}">
<Setter Property="Padding" Value="0" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="HorizontalContentAlignment" Value="Right" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Metro:SegmentItem}">
<Border x:Name="Bd"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="true" UseLayoutRounding="True">
<ContentPresenter Margin="20,8,20,8"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!--<Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.MouseOver.Background}" />-->
<Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.MouseOver.Border}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<!--<Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.MouseOver.Background}" />-->
<Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.MouseOver.Border}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="False" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="#232428" />
<Setter Property="Foreground" Value="{StaticResource Item.SelectedActive.foreground}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="True" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="#232428" />
<Setter Property="Foreground" Value="{StaticResource Item.SelectedActive.foreground}" />
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Bd" Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--#endregion-->
<!--设置窗口属性行样式-->
<Style TargetType="DockPanel" x:Key="SettingItem">
<Setter Property="Height" Value="35"></Setter>
<Setter Property="Margin" Value="10"></Setter>
<Setter Property="VerticalAlignment" Value="Top"></Setter>
</Style>
<!--设置窗口属性行标题-->
<Style TargetType="TextBlock" x:Key="SettingItemText">
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="HorizontalAlignment" Value="Left"></Setter>
<Setter Property="VerticalAlignment" Value="Center"></Setter>
<Setter Property="Width" Value="100"></Setter>
<Setter Property="TextAlignment" Value="Left"></Setter>
</Style>
</ResourceDictionary>

View File

@ -0,0 +1,10 @@
<UserControl x:Class="JianGongYun.TRTC.Components.SytemGatherVolumeControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:JianGongYun.TRTC.Components"
xmlns:Metro="clr-namespace:AduSkin.Controls.Metro;assembly=AduSkin"
mc:Ignorable="d"
Width="auto">
</UserControl>

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace JianGongYun.TRTC.Components
{
/// <summary>
/// SytemGatherVolumeControl.xaml 的交互逻辑
/// </summary>
public partial class SytemGatherVolumeControl : UserControl
{
public SytemGatherVolumeControl()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,127 @@
using JianGongYun.TRTC.Models;
using JianGongYun.TRTC.Utils;
using JianGongYun.TRTC.Windows;
using ManageLiteAV;
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
namespace JianGongYun.TRTC
{
/// <summary>
/// 直播调用对象全放这里
/// </summary>
public static class LiveClassroom
{
const uint SDKAppID = 1400463444;
const string SDKAppKEY = "6ee2586282eb8ab5bff3f917b44500c4ffd9bbd3d820258b1fa8cdd470cfd1ee";
/// <summary>
/// TRTC实例
/// </summary>
public static ITRTCCloud lTRTCCloud;
/// <summary>
/// 设备管理器
/// </summary>
public static ITXDeviceManager lTXDeviceManager;
/// <summary>
/// live窗口的调用窗口
/// </summary>
public static Window CallerWindow { get; private set; }
/// <summary>
/// 直播窗口
/// </summary>
public static Window CurrentLiveWindow;
public static ClassroomEntity CurrentClassroomEntity { get; private set; }
//public static int UserCount = 999;
/// <summary>
/// 进入直播教室
/// </summary>
/// <param name="callerWindow">调用窗口</param>
/// <param name="classroomEntity">教室数据</param>
public static void EnterTheClassroom(Window callerWindow, ClassroomEntity classroomEntity)
{
if (CurrentLiveWindow != null)
{
_ = AduSkin.Controls.Metro.AduMessageBox.Show("已经进入教室", "提醒");
CurrentLiveWindow.Topmost = true;
return;
}
CallerWindow = callerWindow;
CurrentClassroomEntity = classroomEntity;
CurrentLiveWindow = new LiveWindow();
CurrentLiveWindow.Closed += CurrentLiveWindow_Closed;
lTRTCCloud = ITRTCCloud.getTRTCShareInstance();//创建TRTC实例
var roomPars = new TRTCParams
{
sdkAppId = SDKAppID,
userId = CurrentClassroomEntity.TeacherId,
userSig = GenTestUserSig(CurrentClassroomEntity.TeacherId),
roomId = 0,//使用strRoomId
strRoomId = CurrentClassroomEntity.TeacherId,
role = TRTCRoleType.TRTCRoleAnchor
};
lTRTCCloud.enterRoom(ref roomPars, TRTCAppScene.TRTCAppSceneLIVE);//创建房间
//设备
var settingViewMode = ViewModels.SettingWindowViewModel.GetInstance();
lTXDeviceManager = lTRTCCloud.getDeviceManager();
var currentMic = settingViewMode.CurrentMic;//麦克风
if (!string.IsNullOrEmpty(currentMic))
{
var res = lTXDeviceManager.setCurrentDevice(TRTCDeviceType.TXMediaDeviceTypeMic, currentMic);
Console.WriteLine($"设置麦克风:{res}");
}
//设备完结
callerWindow.Hide();//隐藏调用窗口
CurrentLiveWindow.Show();
}
private static void CurrentLiveWindow_Closed(object sender, EventArgs e)
{
CurrentLiveWindow = null;
CurrentClassroomEntity = null;
CallerWindow.Show();//还原调用者窗口
lTXDeviceManager.Dispose();
lTXDeviceManager = null;
lTRTCCloud.exitRoom();
ITRTCCloud.destroyTRTCShareInstance();//销毁TRTC实例
lTRTCCloud.Dispose();
lTRTCCloud = null;
}
/// <summary>
/// 计算 UserSig 签名
///
/// 函数内部使用 HMAC-SHA256 非对称加密算法,对 SDKAPPID、userId 和 EXPIRETIME 进行加密
///
/// 该方案仅适合本地跑通demo和功能调试产品真正上线发布要使用服务器获取方案避免私钥被破解。
/// </summary>
/// <remarks>
/// 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
///
/// 本文件中的代码虽然能够正确计算出 UserSig但仅适合快速调通 SDK 的基本功能,不适合线上产品,
/// 这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
/// 一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
///
/// 正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
/// 由于破解服务器的成本要高于破解客户端 App所以服务器计算的方案能够更好地保护您的加密密钥。
///
/// 文档https://cloud.tencent.com/document/product/647/17275#GetFromServer
/// </remarks>
public static string GenTestUserSig(string userId)
{
if (SDKAppID == 0 || string.IsNullOrEmpty(SDKAppKEY)) return null;
TLSSigAPIv2 api = new TLSSigAPIv2((int)SDKAppID, SDKAppKEY);
// 统一转换为UTF8SDK内部是用UTF8编码。
return api.GenSig(Util.UTF16To8(userId));
}
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace JianGongYun.TRTC.Models
{
/// <summary>
/// 教室实体数据
/// </summary>
public class ClassroomEntity
{
/// <summary>
/// 教师id(长度不超过32字符,教师id同时视为直播教室id)
/// </summary>
public string TeacherId { get; set; }
/// <summary>
/// 教师名称
/// </summary>
public string TeacherName { get; set; }
/// <summary>
/// 课程名称
/// </summary>
public string ClassHead { get; set; }
/// <summary>
/// 章节名称
/// </summary>
public string ClassSubHead { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace JianGongYun.TRTC.Models
{
public class ComboBoxEntity
{
public string Id { get; set; }
public string Text { get; set; }
}
}

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace JianGongYun.TRTC.Utils
{
public class IniStorage
{ // 声明INI文件的写操作函数
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
// 声明INI文件的读操作函数
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, System.Text.StringBuilder retVal, int size, string filePath);
private string sPath = null;
public IniStorage(string path)
{
this.sPath = path;
}
public void SetValue(string section, string key, string value)
{
// section=配置节key=键名value=键值path=路径
WritePrivateProfileString(section, key, value, sPath);
}
public string GetValue(string section, string key)
{
// 每次从ini中读取多少字节
System.Text.StringBuilder temp = new System.Text.StringBuilder(255);
// section=配置节key=键名temp=上面path=路径
GetPrivateProfileString(section, key, "", temp, 255, sPath);
return temp.ToString();
}
}
}

View File

@ -0,0 +1,123 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using zlib;
namespace JianGongYun.TRTC.Utils
{
public class TLSSigAPIv2
{
private readonly int sdkappid;
private readonly string key;
public TLSSigAPIv2(int sdkappid, string key)
{
this.sdkappid = sdkappid;
this.key = key;
}
private static byte[] CompressBytes(byte[] sourceByte)
{
MemoryStream inputStream = new MemoryStream(sourceByte);
Stream outStream = CompressStream(inputStream);
byte[] outPutByteArray = new byte[outStream.Length];
outStream.Position = 0;
outStream.Read(outPutByteArray, 0, outPutByteArray.Length);
return outPutByteArray;
}
private static Stream CompressStream(Stream sourceStream)
{
MemoryStream streamOut = new MemoryStream();
ZOutputStream streamZOut = new ZOutputStream(streamOut, zlibConst.Z_DEFAULT_COMPRESSION);
CopyStream(sourceStream, streamZOut);
streamZOut.finish();
return streamOut;
}
public static void CopyStream(System.IO.Stream input, System.IO.Stream output)
{
byte[] buffer = new byte[2000];
int len;
while ((len = input.Read(buffer, 0, 2000)) > 0)
{
output.Write(buffer, 0, len);
}
output.Flush();
}
private string HMACSHA256(string identifier, long currTime, int expire, string base64UserBuf, bool userBufEnabled)
{
string rawContentToBeSigned = "TLS.identifier:" + identifier + "\n"
+ "TLS.sdkappid:" + sdkappid + "\n"
+ "TLS.time:" + currTime + "\n"
+ "TLS.expire:" + expire + "\n";
if (true == userBufEnabled)
{
rawContentToBeSigned += "TLS.userbuf:" + base64UserBuf + "\n";
}
using (HMACSHA256 hmac = new HMACSHA256())
{
UTF8Encoding encoding = new UTF8Encoding();
Byte[] textBytes = encoding.GetBytes(rawContentToBeSigned);
Byte[] keyBytes = encoding.GetBytes(key);
Byte[] hashBytes;
using (HMACSHA256 hash = new HMACSHA256(keyBytes))
hashBytes = hash.ComputeHash(textBytes);
return Convert.ToBase64String(hashBytes);
}
}
private string GenSig(string identifier, int expire, byte[] userbuf, bool userBufEnabled)
{
DateTime epoch = new DateTime(1970, 1, 1); // unix 时间戳
Int64 currTime = (Int64)(DateTime.UtcNow - epoch).TotalMilliseconds / 1000;
string base64UserBuf;
string jsonData;
if (true == userBufEnabled)
{
base64UserBuf = Convert.ToBase64String(userbuf);
string base64sig = HMACSHA256(identifier, currTime, expire, base64UserBuf, userBufEnabled);
var jsonObj = new JObject();
jsonObj["TLS.ver"] = "2.0";
jsonObj["TLS.identifier"] = identifier;
jsonObj["TLS.sdkappid"] = sdkappid;
jsonObj["TLS.expire"] = expire;
jsonObj["TLS.time"] = currTime;
jsonObj["TLS.sig"] = base64sig;
jsonObj["TLS.userbuf"] = base64UserBuf;
jsonData = JsonConvert.SerializeObject(jsonObj);
}
else
{
string base64sig = HMACSHA256(identifier, currTime, expire, "", false);
var jsonObj = new JObject();
jsonObj["TLS.ver"] = "2.0";
jsonObj["TLS.identifier"] = identifier;
jsonObj["TLS.sdkappid"] = sdkappid;
jsonObj["TLS.expire"] = expire;
jsonObj["TLS.time"] = currTime;
jsonObj["TLS.sig"] = base64sig;
jsonData = JsonConvert.SerializeObject(jsonObj);
}
byte[] buffer = Encoding.UTF8.GetBytes(jsonData);
return Convert.ToBase64String(CompressBytes(buffer))
.Replace('+', '*').Replace('/', '-').Replace('=', '_');
}
public string GenSig(string identifier, int expire = 180 * 86400)
{
return GenSig(identifier, expire, null, false);
}
public string GenSigWithUserBuf(string identifier, int expire, byte[] userbuf)
{
return GenSig(identifier, expire, userbuf, true);
}
}
}

View File

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace JianGongYun.TRTC.Utils
{
public class Util
{
public static string UTF16To8(string str)
{
byte[] utf16Bytes = Encoding.Unicode.GetBytes(str);
byte[] utf8Bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, utf16Bytes);
return Encoding.UTF8.GetString(utf8Bytes);
}
public static bool IsSys64bit()
{
return IntPtr.Size == 8;
}
public static string GetRandomString(int iLength)
{
string buffer = "0123456789";
StringBuilder sb = new StringBuilder();
Random r = new Random(iLength);
int range = buffer.Length;
for (int i = 0; i < iLength; i++)
{
sb.Append(buffer.Substring(r.Next(range), 1));
}
return sb.ToString();
}
public static string MD5(string str)
{
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] byteOld = Encoding.UTF8.GetBytes(str);
byte[] byteNew = md5.ComputeHash(byteOld);
StringBuilder sb = new StringBuilder();
foreach (byte b in byteNew)
{
// 将字节转换成16进制表示的字符串
sb.Append(b.ToString("x2"));
}
return sb.ToString();
}
public static bool IsTestEnv()
{
string path = Environment.CurrentDirectory + "\\ShowTestEnv.txt";
return File.Exists(path);
}
public static string ConvertMSToTime(int lCurMS, int lDurationMS)
{
string strTime = "00:00/00:00";
int nTotalDurationSecond = lDurationMS / 1000;
int nDurationMinute = nTotalDurationSecond / 60;
int nDurationSecond = nTotalDurationSecond % 60;
int nTotalCurSecond = lCurMS / 1000;
int nCurMinute = nTotalCurSecond / 60;
int nCurSecond = nTotalCurSecond % 60;
string format = "{0:00}:{1:00}/{2:00}:{3:00}";
strTime = string.Format(format, nCurMinute, nCurSecond, nDurationMinute, nDurationSecond);
return strTime;
}
}
}

View File

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;
namespace JianGongYun.TRTC.ViewModels
{
public class LiveWindowViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// 教室信息
/// </summary>
public Models.ClassroomEntity ClassroomEntity { get { return LiveClassroom.CurrentClassroomEntity; } }
/// <summary>
/// 学生总数
/// </summary>
private int _StudentCount = 0;
public int StudentCount
{
set
{
_StudentCount = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("StudentCount"));//对StudentCount进行监听
}
}
get
{
return _StudentCount;
}
}
/// <summary>
/// 是否在直播中
/// </summary>
private bool _IsLive = false;
public bool IsLive
{
set
{
_IsLive = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("IsLive"));
}
}
get
{
return _IsLive;
}
}
}
}

View File

@ -0,0 +1,304 @@
using JianGongYun.TRTC.Models;
using JianGongYun.TRTC.Utils;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;
using System.Linq;
using System.Windows.Controls;
using JianGongYun.TRTC.Components;
using System.Windows;
namespace JianGongYun.TRTC.ViewModels
{
public class SettingWindowViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// 单例
/// </summary>
private static SettingWindowViewModel _Instance;
public static SettingWindowViewModel GetInstance()
{
if (_Instance == null)
{
_Instance = new SettingWindowViewModel();
}
return _Instance;
}
/// <summary>
/// 直播主窗口viewmodel
/// </summary>
private LiveWindowViewModel LiveWindowViewModel
{
get
{
return LiveClassroom.CurrentLiveWindow.DataContext == null ? null : LiveClassroom.CurrentLiveWindow.DataContext as LiveWindowViewModel;
}
}
#region
/// <summary>
/// 集合,实时获取
/// </summary>
public List<ComboBoxEntity> MicList
{
get
{
var mics = LiveClassroom.lTXDeviceManager.getDevicesList(ManageLiteAV.TRTCDeviceType.TXMediaDeviceTypeMic);
List<ComboBoxEntity> micList = new List<ComboBoxEntity>();
var count = mics.getCount();
for (uint i = 0; i < count; i++)
{
var temp = new ComboBoxEntity { Id = mics.getDevicePID(i), Text = mics.getDeviceName(i) };
micList.Add(temp);
}
return micList;
}
}
/// <summary>
/// 当前
/// </summary>
private string _CurrentMic;
public string CurrentMic
{
get
{
var tempList = this.MicList;
if (tempList.Count == 0)
{
return null;
}
if (string.IsNullOrEmpty(_CurrentMic) || !tempList.Any(a => a.Id == _CurrentMic))//第一次取或者设备发生变动找不到上次的选择
{
var localMic = storage.GetValue(INI_ROOT_KEY, INI_KEY_CHOOSE_MIC);//本地缓存
if (string.IsNullOrEmpty(localMic))//本地没有就取第一个
{
_CurrentMic = tempList.First().Id;
storage.SetValue(INI_ROOT_KEY, INI_KEY_CHOOSE_MIC, _CurrentMic);//生成初始数据
}
else
{
_CurrentMic = localMic;
var temp = tempList.Where(a => a.Id == localMic).FirstOrDefault();
if (temp == null)//找不到上次缓存的设备就取第一个
{
_CurrentMic = tempList.First().Id;
storage.SetValue(INI_ROOT_KEY, INI_KEY_CHOOSE_MIC, _CurrentMic);//生成初始数据
}
}
}
return _CurrentMic;
}
set
{
_CurrentMic = value;
storage.SetValue(INI_ROOT_KEY, INI_KEY_CHOOSE_MIC, value);//生成保存本地
LiveClassroom.lTXDeviceManager.setCurrentDevice(ManageLiteAV.TRTCDeviceType.TXMediaDeviceTypeMic, _CurrentMic);//设置麦克
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("CurrentMic"));//对CurrentMic进行监听
}
}
}
/// <summary>
/// 麦克风采集音量
/// </summary>
private uint _MicVolume = 100;
public uint MicVolume
{
get
{
var micVolume = storage.GetValue(INI_ROOT_KEY, INI_KEY_AUDIO_MIC_VOLUME);//本地缓存
if (string.IsNullOrEmpty(micVolume))//本地没有就取第一个
{
storage.SetValue(INI_ROOT_KEY, INI_KEY_AUDIO_MIC_VOLUME, _MicVolume.ToString());//生成初始数据
}
else
{
_MicVolume = uint.Parse(micVolume);
}
return _MicVolume;
}
set
{
_MicVolume = value;
storage.SetValue(INI_ROOT_KEY, INI_KEY_AUDIO_MIC_VOLUME, value.ToString());//生成保存本地
var res = LiveClassroom.lTXDeviceManager.setCurrentDeviceVolume(ManageLiteAV.TRTCDeviceType.TXMediaDeviceTypeMic, _MicVolume);//设置麦克音量
Console.WriteLine("设置麦克风采集音量" + res);
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("MicVolume"));
}
}
}
#endregion
#region
/// <summary>
/// 音频来源
/// </summary>
private string _AudioSource = "1";
public string AudioSource
{
get
{
var audioSource = storage.GetValue(INI_ROOT_KEY, INI_KEY_AUDIO_SOURCE);//本地缓存
if (string.IsNullOrEmpty(audioSource))//本地没有就取第一个
{
storage.SetValue(INI_ROOT_KEY, INI_KEY_AUDIO_SOURCE, _AudioSource);//生成初始数据
}
else
{
_AudioSource = audioSource;
}
return _AudioSource;
}
set
{
_AudioSource = value;
storage.SetValue(INI_ROOT_KEY, INI_KEY_AUDIO_SOURCE, value);//生成保存本地
if (_AudioSource == "1")//只采集麦克风,关闭系统音采集
{
ShowSytemGatherSlider = Visibility.Hidden;
LiveClassroom.lTRTCCloud.stopSystemAudioLoopback();
}
else if (_AudioSource == "2")//麦和系统音,开启采集系统音
{
ShowSytemGatherSlider = Visibility.Visible;
LiveClassroom.lTRTCCloud.startSystemAudioLoopback(null);
}
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("AudioSource"));
}
}
}
/// <summary>
/// 是否显示系统采集滑动条
/// </summary>
private Visibility _ShowSytemGatherSlider = Visibility.Hidden;
public Visibility ShowSytemGatherSlider
{
get
{
if (AudioSource=="2")
{
_ShowSytemGatherSlider = Visibility.Visible;
}
else
{
_ShowSytemGatherSlider = Visibility.Hidden;
}
return _ShowSytemGatherSlider;
}
set
{
_ShowSytemGatherSlider = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("ShowSytemGatherSlider"));
}
}
}
/// <summary>
/// 系统采集音量
/// </summary>
private uint _SytemGatherVolume = 100;
public uint SytemGatherVolume
{
get
{
var sytemGatherVolume = storage.GetValue(INI_ROOT_KEY, INI_KEY_AUDIO_SYSTEM_GATHER_VOLUME);//本地缓存
if (string.IsNullOrEmpty(sytemGatherVolume))//本地没有就取第一个
{
storage.SetValue(INI_ROOT_KEY, INI_KEY_AUDIO_SYSTEM_GATHER_VOLUME, _SytemGatherVolume.ToString());//生成初始数据
}
else
{
_SytemGatherVolume = uint.Parse(sytemGatherVolume);
}
return _SytemGatherVolume;
}
set
{
_SytemGatherVolume = value;
storage.SetValue(INI_ROOT_KEY, INI_KEY_AUDIO_SYSTEM_GATHER_VOLUME, value.ToString());//生成保存本地
LiveClassroom.lTRTCCloud.setSystemAudioLoopbackVolume(_SytemGatherVolume);//设置系统采集音量
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("SytemGatherVolume"));
}
}
}
#endregion
/// <summary>
/// ini文件操作
/// </summary>
private IniStorage storage;
private SettingWindowViewModel()
{
storage = new IniStorage(sPath);
}
#region
//配置文件路径
private string sPath = ".\\TRTCConfig.ini";
//根节点
public const string INI_ROOT_KEY = "TRTCLOCALCONFIG";
// 设备
public const string INI_KEY_CHOOSE_CAMERA = "INI_KEY_CHOOSE_CAMERA";//当前摄像头
public const string INI_KEY_CHOOSE_MIC = "INI_KEY_CHOOSE_MIC";//当前麦克风
// 音频
public const string INI_KEY_AUDIO_MIC_VOLUME = "INI_KEY_AUDIO_MIC_VOLUME";//麦克风音量
public const string INI_KEY_AUDIO_SPEAKER_VOLUME = "INI_KEY_AUDIO_SOURCE";//播放音量
public const string INI_KEY_AUDIO_SOURCE = "INI_KEY_AUDIO_SOURCE";//音频来源
public const string INI_KEY_AUDIO_SYSTEM_GATHER_VOLUME = "INI_KEY_AUDIO_SYSTEM_GATHER_VOLUME";//麦克风音量
// 视频
public const string INI_KEY_VIDEO_FPS = "INI_KEY_VIDEO_FPS";//视频FPS
public const string INI_KEY_VIDEO_BITRATE = "INI_KEY_VIDEO_BITRATE";
public const string INI_KEY_VIDEO_RESOLUTION = "INI_KEY_VIDEO_RESOLUTION";
public const string INI_KEY_VIDEO_RES_MODE = "INI_KEY_VIDEO_RES_MODE";
public const string INI_KEY_VIDEO_QUALITY = "INI_KEY_VIDEO_QUALITY";
public const string INI_KEY_VIDEO_QUALITY_CONTROL = "INI_KEY_VIDEO_QUALITY_CONTROL";
public const string INI_KEY_VIDEO_APP_SCENE = "INI_KEY_VIDEO_APP_SCENE";
public const string INI_KEY_VIDEO_FILL_MODE = "INI_KEY_VIDEO_FILL_MODE";
public const string INI_KEY_VIDEO_ROTATION = "INI_KEY_VIDEO_ROTATION";
// 美颜
public const string INI_KEY_BEAUTY_OPEN = "INI_KEY_BEAUTY_OPEN";
public const string INI_KEY_BEAUTY_STYLE = "INI_KEY_BEAUTY_STYLE";
public const string INI_KEY_BEAUTY_VALUE = "INI_KEY_BEAUTY_VALUE";
public const string INI_KEY_WHITE_VALUE = "INI_KEY_WHITE_VALUE";
public const string INI_KEY_RUDDINESS_VALUE = "INI_KEY_RUDDINESS_VALUE";
// 大小流
public const string INI_KEY_SET_PUSH_SMALLVIDEO = "INI_KEY_SET_PUSH_SMALLVIDEO";
public const string INI_KEY_SET_PLAY_SMALLVIDEO = "INI_KEY_SET_PLAY_SMALLVIDEO";
// 测试
public const string INI_KEY_SET_NETENV_STYLE = "INI_KEY_SET_NETENV_STYLE";
public const string INI_KEY_ROOMCALL_STYLE = "INI_KEY_ROOMCALL_STYLE";
// 镜像
public const string INI_KEY_LOCAL_VIDEO_MIRROR = "INI_KEY_LOCAL_VIDEO_MIRROR";
public const string INI_KEY_REMOTE_VIDEO_MIRROR = "INI_KEY_REMOTE_VIDEO_MIRROR";
// 音量提示
public const string INI_KEY_SHOW_AUDIO_VOLUME = "INI_KEY_SHOW_AUDIO_VOLUME";
// 混流
public const string INI_KEY_CLOUD_MIX_TRANSCODING = "INI_KEY_CLOUD_MIX_TRANSCODING";
#endregion
}
}

View File

@ -0,0 +1,55 @@
<Metro:MetroWindow x:Class="JianGongYun.TRTC.Windows.LiveWindow"
xmlns:Metro="clr-namespace:AduSkin.Controls.Metro;assembly=AduSkin"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:JianGongYun.TRTC.Windows"
xmlns:live="clr-namespace:JianGongYun.TRTC"
mc:Ignorable="d"
Title="建工云课堂" MinWidth="600" MinHeight="350"
d:DesignHeight="1200" d:DesignWidth="1600"
BorderThickness="0" WindowStyle="None"
WindowStartupLocation="CenterOwner"
Background="#232428">
<!--窗口填满-->
<Metro:MetroWindow.Resources>
<Geometry x:Key="Icon_Browser">M512 884.363636c-50.059636 0-98.722909-9.890909-144.64-29.393454a372.922182 372.922182 0 0 1-118.365091-79.965091 372.922182 372.922182 0 0 1-79.965091-118.365091A367.872 367.872 0 0 1 139.636364 512c0-50.036364 9.890909-98.722909 29.393454-144.64a372.945455 372.945455 0 0 1 79.965091-118.365091 372.922182 372.922182 0 0 1 118.365091-79.965091A367.872 367.872 0 0 1 512 139.636364c50.059636 0 98.722909 9.890909 144.64 29.393454a372.945455 372.945455 0 0 1 118.365091 79.965091 372.922182 372.922182 0 0 1 79.965091 118.365091A367.872 367.872 0 0 1 884.363636 512c0 50.059636-9.890909 98.722909-29.393454 144.64a372.945455 372.945455 0 0 1-79.965091 118.365091 372.922182 372.922182 0 0 1-118.365091 79.965091A367.848727 367.848727 0 0 1 512 884.363636z m0-698.181818c-43.776 0-86.341818 8.634182-126.464 25.693091a326.516364 326.516364 0 0 0-103.633455 70.050909 326.516364 326.516364 0 0 0-70.027636 103.610182A321.629091 321.629091 0 0 0 186.181818 512c0 43.776 8.634182 86.341818 25.693091 126.464a326.516364 326.516364 0 0 0 70.050909 103.633455 326.516364 326.516364 0 0 0 103.610182 70.027636A321.652364 321.652364 0 0 0 512 837.818182c43.776 0 86.341818-8.657455 126.464-25.693091a326.516364 326.516364 0 0 0 103.633455-70.050909 326.516364 326.516364 0 0 0 70.027636-103.610182A321.652364 321.652364 0 0 0 837.818182 512c0-43.776-8.657455-86.341818-25.693091-126.464a326.516364 326.516364 0 0 0-70.050909-103.633455 326.516364 326.516364 0 0 0-103.610182-70.027636A321.652364 321.652364 0 0 0 512 186.181818z m-170.077091 512.162909a18.013091 18.013091 0 0 1-17.408-22.667636l70.865455-265.774546a18.013091 18.013091 0 0 1 12.753454-12.753454l265.774546-70.865455a18.013091 18.013091 0 0 1 22.039272 22.039273l-70.865454 265.774546a18.013091 18.013091 0 0 1-12.776727 12.753454L346.554182 697.716364a18.013091 18.013091 0 0 1-4.654546 0.628363z m85.573818-269.079272l-60.16 225.62909 225.605818-60.16 60.16-225.62909-225.605818 60.16z m111.755637 126.138181a17.966545 17.966545 0 0 1-12.730182-5.282909l-46.801455-46.778182a18.013091 18.013091 0 1 1 25.483637-25.506909l46.778181 46.801455a18.013091 18.013091 0 0 1-12.730181 30.766545z</Geometry>
</Metro:MetroWindow.Resources>
<Canvas x:Name="Root" Background="Transparent">
<!--父容器填满-->
<DockPanel Panel.ZIndex="0" Height="{Binding ElementName=Root,Path=ActualHeight}" Width="{Binding ElementName=Root,Path=ActualWidth}">
<!--上方标题面板-->
<Canvas DockPanel.Dock="Top" Height="60" Background="#232428">
<StackPanel Height="30">
<TextBlock VerticalAlignment="Center" FontSize="16" Padding="20 6" Foreground="White">
<Bold>
《<Run Text="{Binding ClassroomEntity.ClassHead,Mode=OneTime}"></Run>》
</Bold>
</TextBlock>
</StackPanel>
<StackPanel FlowDirection="LeftToRight" Orientation="Horizontal" Canvas.Top="30" Height="25">
<TextBlock FontSize="14" Padding="25 0 0 0" Foreground="#bbbbbb" Text="{Binding ClassroomEntity.ClassSubHead,Mode=OneTime}"></TextBlock>
<TextBlock FontSize="14" Padding="15 0 0 0" Foreground="#bbbbbb" Text="当前教室共有:"></TextBlock>
<TextBlock FontSize="14" Foreground="#3d7cf9" Text="{Binding StudentCount,Mode=OneWay}"></TextBlock>
<TextBlock FontSize="14" Padding="3 0 0 0" Foreground="#bbbbbb" Text="人"></TextBlock>
</StackPanel>
</Canvas>
<!--右方聊天学员面板-->
<Canvas DockPanel.Dock="Right" Width="280" Background="#2f3035">
</Canvas>
<!--下方教程面板-->
<Canvas DockPanel.Dock="Bottom" Height="30" Background="#2a2b30">
</Canvas>
<!--下方设置面板-->
<Canvas DockPanel.Dock="Bottom" Height="70" Background="#232428">
<!--设置按钮-->
<Metro:AduSysButton Click="Setting_Btn_Click" Foreground="#fff" Canvas.Left="20" Canvas.Top="15" CornerRadius="6" Height="40" Width="40" Icon="{StaticResource Icon_Browser}" Content="" />
</Canvas>
<!--中间面板-->
<Canvas Background="#151618">
</Canvas>
</DockPanel>
</Canvas>
</Metro:MetroWindow>

View File

@ -0,0 +1,49 @@
using AduSkin.Controls.Metro;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Linq;
namespace JianGongYun.TRTC.Windows
{
/// <summary>
/// LiveWindow.xaml 的交互逻辑
/// </summary>
public partial class LiveWindow : MetroWindow
{
ViewModels.LiveWindowViewModel LiveWindowViewModel;
public LiveWindow()
{
InitializeComponent();
LiveWindowViewModel =new ViewModels.LiveWindowViewModel();
this.DataContext = LiveWindowViewModel;
BorderBrush = new SolidColorBrush(color: Color.FromRgb(42, 43, 48));//窗口标题背景颜色
}
private void aaaa(object sender, RoutedEventArgs e)
{
LiveWindowViewModel.StudentCount++;
}
//设置按钮
private void Setting_Btn_Click(object sender, RoutedEventArgs e)
{
var settingWindow = SettingWindow.GetInstance();
settingWindow.Show();
if (settingWindow.WindowState != WindowState.Normal)
{
settingWindow.WindowState = WindowState.Normal;
}
settingWindow.Topmost = true;
}
}
}

View File

@ -0,0 +1,62 @@
<Metro:MetroWindow x:Class="JianGongYun.TRTC.Windows.SettingWindow"
xmlns:Metro="clr-namespace:AduSkin.Controls.Metro;assembly=AduSkin"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:JianGongYun.TRTC.Windows"
mc:Ignorable="d"
ResizeMode="NoResize"
Title="设置" Height="380" Width="600">
<Metro:MetroWindow.Resources>
<DataTemplate x:Key="CusHeaderTitle1">
<TextBlock Foreground="#aaaaaa" FontWeight="Bold" Background="Transparent">音频设置</TextBlock>
</DataTemplate>
<DataTemplate x:Key="CusHeaderTitle2">
<TextBlock Foreground="#aaaaaa" FontWeight="Bold" Background="Transparent">录屏设置</TextBlock>
</DataTemplate>
<DataTemplate x:Key="CusHeaderTitle3">
<TextBlock Foreground="#aaaaaa" FontWeight="Bold" Background="Transparent">直播设置</TextBlock>
</DataTemplate>
</Metro:MetroWindow.Resources>
<Metro:AduNavigationPanel IndicatorStyle="{StaticResource LeftIndicatorStyle}" IndicatorItemContainerStyle="{StaticResource LeftIndicatorItemStyle}" x:Name="navigationPanel"
Height="auto" Width="auto"
IndicatorMargin="0" IndicatorHorizontalAlignment="Center"
IndicatorSelectedIndex="0" IndicatorPlacement="Left">
<Metro:MetroScrollViewer HorizontalScrollBarVisibility="Disabled">
<StackPanel Background="#232428">
<Metro:AduGroupBoxNor HeaderTemplate="{StaticResource CusHeaderTitle1}" Header="音频设置" HeaderBackground="Transparent" BorderThickness="0" BorderBrush="{StaticResource DefaultBorderBrush}" FontSize="14" HeaderPadding="10,6">
<StackPanel>
<DockPanel Style="{StaticResource SettingItem}">
<TextBlock Style="{StaticResource SettingItemText}" DockPanel.Dock="Left"> 麦克风</TextBlock>
<Metro:AduFlatButton Content="检测麦克风" x:Name="MicTestBtn" Click="TestMic" Width="100" DockPanel.Dock="Right" Margin=" 11 0 10 0" Type="info" />
<Metro:AduComboBox ItemsSource="{Binding MicList,Mode=OneWay}" DisplayMemberPath="Text" SelectedValuePath="Id" SelectedValue="{Binding CurrentMic,Mode=TwoWay}" ComBoxItemPanelBackground="{StaticResource ComboBoxBrush}"></Metro:AduComboBox>
</DockPanel>
<DockPanel Style="{StaticResource SettingItem}">
<TextBlock Style="{StaticResource SettingItemText}" DockPanel.Dock="Left"> 麦采集音量</TextBlock>
<Metro:AduFlatSilder x:Name="Slider1" DecreaseColor="#3e7fff" IncreaseColor="#aaaaaa" Maximum="100" Value="{Binding MicVolume}" Margin="0 0 10 0" Height="17"/>
</DockPanel>
<DockPanel Style="{StaticResource SettingItem}">
<TextBlock Style="{StaticResource SettingItemText}" DockPanel.Dock="Left"> 音频来源</TextBlock>
<Metro:AduComboBox Margin="0 0 10 0" SelectedValuePath="Tag" SelectedValue="{Binding AudioSource}" ComBoxItemPanelBackground="{StaticResource ComboBoxBrush}">
<ComboBoxItem Content="仅麦克风" Tag="1"/>
<ComboBoxItem Content="麦和系统声音" Tag="2" />
</Metro:AduComboBox>
</DockPanel>
<DockPanel Visibility="{Binding ShowSytemGatherSlider}" Style="{StaticResource SettingItem}">
<TextBlock Style="{StaticResource SettingItemText}" DockPanel.Dock="Left"> 系统采集音量</TextBlock>
<Metro:AduFlatSilder x:Name="Slider2" DecreaseColor="#3e7fff" IncreaseColor="#aaaaaa" Maximum="100" Value="{Binding SytemGatherVolume}" Margin="0 0 10 0" Height="17"/>
</DockPanel>
</StackPanel>
</Metro:AduGroupBoxNor>
<Metro:AduGroupBoxNor HeaderTemplate="{StaticResource CusHeaderTitle2}" Header="录屏设置" HeaderBackground="Transparent" BorderThickness="0" BorderBrush="{StaticResource DefaultBorderBrush}" FontSize="14" Height="380" HeaderPadding="10,6">
</Metro:AduGroupBoxNor>
<Metro:AduGroupBoxNor HeaderTemplate="{StaticResource CusHeaderTitle3}" Header="直播设置" HeaderBackground="Transparent" BorderThickness="0" BorderBrush="{StaticResource DefaultBorderBrush}" FontSize="14" Height="380" HeaderPadding="10,6">
</Metro:AduGroupBoxNor>
</StackPanel>
</Metro:MetroScrollViewer>
</Metro:AduNavigationPanel>
</Metro:MetroWindow>

View File

@ -0,0 +1,91 @@
using AduSkin.Controls.Metro;
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace JianGongYun.TRTC.Windows
{
/// <summary>
/// SettingWindow.xaml 的交互逻辑
/// </summary>
public partial class SettingWindow : MetroWindow
{
/// <summary>
/// 单例
/// </summary>
private static SettingWindow _Instance;
public static SettingWindow GetInstance()
{
if (_Instance == null)
{
_Instance = new SettingWindow();
}
return _Instance;
}
protected override void OnClosed(EventArgs e)
{
_Instance = null;
if (micTesting)//关闭麦克风测试
{
LiveClassroom.lTXDeviceManager.stopMicDeviceTest();
}
base.OnClosed(e);
}
ViewModels.SettingWindowViewModel mode = ViewModels.SettingWindowViewModel.GetInstance();
private SettingWindow()
{
InitializeComponent();
BorderBrush = new SolidColorBrush(color: Color.FromRgb(42, 43, 48));//窗口标题背景颜色
this.DataContext = mode;
}
bool micTesting = false;
private void TestMic(object sender, RoutedEventArgs e)
{
if (micTesting)
{
LiveClassroom.lTXDeviceManager.stopMicDeviceTest();
this.Dispatcher.Invoke(new Action(() =>
{
this.MicTestBtn.Content = "检测麦克风";
this.MicTestBtn.Type = AduSkin.Controls.FlatButtonSkinEnum.info;
micTesting = false;
}));
}
else
{
if (LiveClassroom.lTXDeviceManager.startMicDeviceTest(1000) == 0)
{
this.Dispatcher.Invoke(new Action(() =>
{
this.MicTestBtn.Content = "停止检测";
this.MicTestBtn.Type = AduSkin.Controls.FlatButtonSkinEnum.error;
micTesting = true;
}));
}
else
{
AduMessageBox.Show("测试失败", "提醒");
}
}
}
protected override void OnActivated(EventArgs e)
{
base.OnActivated(e);
//滑动条颜色前台设置无效,手动调用才行
var sliderColor = (SolidColorBrush)(new BrushConverter().ConvertFrom("#3e7fff"));
Slider1.DecreaseColor = sliderColor;
Slider2.DecreaseColor = sliderColor;
}
}
}

View File

@ -21,40 +21,45 @@
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<ListBox ItemsSource="{Binding AllControlViewSource.View}" BorderThickness="0" Background="#2F3035" SelectedItem="{Binding CurrentShowControl}">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Padding" Value="0" />
<Setter Property="Cursor" Value="Hand"/>
</Style>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<Border MinHeight="40" Width="245" Background="#00000000" x:Name="Bd" BorderBrush="#2F3035" BorderThickness="0 1 0 0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Title}" Foreground="White" Margin="20,0" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</Grid>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Value="True">
<Setter TargetName="Bd" Property="Background" Value="#3E7FFF" />
</DataTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="WhiteSmoke" />
</MultiTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Canvas x:Name="CanvasContent">
<ListBox Height="{Binding ElementName=CanvasContent,Path=ActualHeight}" ItemsSource="{Binding AllControlViewSource.View}" BorderThickness="0" Background="#2F3035" SelectedItem="{Binding CurrentShowControl}">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Padding" Value="0" />
<Setter Property="Cursor" Value="Hand"/>
</Style>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<Border MinHeight="40" Width="245" Background="#00000000" x:Name="Bd" BorderBrush="#2F3035" BorderThickness="0 1 0 0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Title}" Foreground="White" Margin="20,0" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</Grid>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Value="True">
<Setter TargetName="Bd" Property="Background" Value="#3E7FFF" />
</DataTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="WhiteSmoke" />
</MultiTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!--测试按钮-->
<Metro:AduFlatButton Content="直播窗口测试弹出" Click="LiveTest_Click" Canvas.Bottom="100" Canvas.Left="77"></Metro:AduFlatButton>
<!--测试按钮结束-->
</Canvas>
</Grid>
</Border>
<Grid Grid.Column="1">

View File

@ -1,4 +1,5 @@
using System;
using JianGongYun.TRTC;
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
@ -21,5 +22,17 @@ namespace JianGongYun.Views
{
InitializeComponent();
}
private void LiveTest_Click(object sender, RoutedEventArgs e)
{
LiveClassroom.EnterTheClassroom(Window.GetWindow(this),
new TRTC.Models.ClassroomEntity
{
ClassHead = "课程1",
ClassSubHead = "章节1",
TeacherId = "53245345",
TeacherName = "王大锤"
});
}
}
}
}